diff -Naur lammps-14Feb08/doc/atom_modify.html lammps-15Feb08/doc/atom_modify.html
--- lammps-14Feb08/doc/atom_modify.html	2006-09-21 10:22:34.000000000 -0600
+++ lammps-15Feb08/doc/atom_modify.html	2008-02-15 12:09:18.000000000 -0700
@@ -17,15 +17,17 @@
 </PRE>
 <UL><LI>one or more keyword/value pairs may be appended 
 
-<LI>keyword = <I>map</I> 
+<LI>keyword = <I>map</I> or <I>first</I> 
 
-<PRE>  <I>map</I> value = <I>array</I> or <I>hash</I> 
+<PRE>  <I>map</I> value = <I>array</I> or <I>hash</I>
+  <I>first</I> value = group-ID = group whose atoms will appear first in internal atom lists 
 </PRE>
 
 </UL>
 <P><B>Examples:</B>
 </P>
-<PRE>atom_modify map hash 
+<PRE>atom_modify map hash
+atom_modify first colloid 
 </PRE>
 <P><B>Description:</B>
 </P>
@@ -43,6 +45,26 @@
 proportional to N/P on each processor, where P is the total number of
 processors running the simulation.
 </P>
+<P>The <I>first</I> keyword allows a <A HREF = "group.html">group</A> to be specified whose
+atoms will be maintained as the first atoms in each processor's list
+of owned atoms.  This in only useful when the specified group is a
+small fraction of all the atoms, and there are other operations LAMMPS
+is performing that will be sped-up significantly by being able to loop
+over the smaller set of atoms.  Otherwise the reordering required by
+this option will be a net slow-down.  The <A HREF = "neigh_modify.html">neigh_modify
+include</A> and <A HREF = "communicate.html">communicate group</A>
+commands are two examples of commands that require this setting to
+work efficiently.  Several <A HREF = "fix.html">fixes</A>, most notably time
+integration fixes like <A HREF = "fix_nve.html">fix nve</A>, also take advantage of
+this setting if the group they operate on is the group specified by
+this command.
+</P>
+<P>Note that because the atom_modify command must be used in an input
+script before a simulation is setup and groups are defined, this means
+the <I>first</I> keyword will specify a group that is not yet defined.
+This is OK; LAMMPS will check that the group exists before the first
+simulation is performed.
+</P>
 <P><B>Restrictions:</B>
 </P>
 <P>This command must be used before the simulation box is defined by a
@@ -52,7 +74,8 @@
 </P>
 <P><B>Default:</B>
 </P>
-<P>By default, atomic (non-molecular) problems do not allocate maps.
-For molecular problems, the option default is map = array.
+<P>By default, atomic (non-molecular) problems do not allocate maps.  For
+molecular problems, the option default is map = array.  By default,
+first = all.
 </P>
 </HTML>
diff -Naur lammps-14Feb08/doc/atom_modify.txt lammps-15Feb08/doc/atom_modify.txt
--- lammps-14Feb08/doc/atom_modify.txt	2006-09-21 10:22:34.000000000 -0600
+++ lammps-15Feb08/doc/atom_modify.txt	2008-02-15 12:09:18.000000000 -0700
@@ -13,13 +13,15 @@
 atom_modify keyword value ... :pre
 
 one or more keyword/value pairs may be appended :ulb,l
-keyword = {map} :l
-  {map} value = {array} or {hash} :pre
+keyword = {map} or {first} :l
+  {map} value = {array} or {hash}
+  {first} value = group-ID = group whose atoms will appear first in internal atom lists :pre
 :ule
 
 [Examples:]
 
-atom_modify map hash :pre
+atom_modify map hash
+atom_modify first colloid :pre
 
 [Description:]
 
@@ -37,6 +39,26 @@
 proportional to N/P on each processor, where P is the total number of
 processors running the simulation.
 
+The {first} keyword allows a "group"_group.html to be specified whose
+atoms will be maintained as the first atoms in each processor's list
+of owned atoms.  This in only useful when the specified group is a
+small fraction of all the atoms, and there are other operations LAMMPS
+is performing that will be sped-up significantly by being able to loop
+over the smaller set of atoms.  Otherwise the reordering required by
+this option will be a net slow-down.  The "neigh_modify
+include"_neigh_modify.html and "communicate group"_communicate.html
+commands are two examples of commands that require this setting to
+work efficiently.  Several "fixes"_fix.html, most notably time
+integration fixes like "fix nve"_fix_nve.html, also take advantage of
+this setting if the group they operate on is the group specified by
+this command.
+
+Note that because the atom_modify command must be used in an input
+script before a simulation is setup and groups are defined, this means
+the {first} keyword will specify a group that is not yet defined.
+This is OK; LAMMPS will check that the group exists before the first
+simulation is performed.
+
 [Restrictions:]
 
 This command must be used before the simulation box is defined by a
@@ -46,5 +68,6 @@
 
 [Default:]
 
-By default, atomic (non-molecular) problems do not allocate maps.
-For molecular problems, the option default is map = array.
+By default, atomic (non-molecular) problems do not allocate maps.  For
+molecular problems, the option default is map = array.  By default,
+first = all.
diff -Naur lammps-14Feb08/doc/communicate.html lammps-15Feb08/doc/communicate.html
--- lammps-14Feb08/doc/communicate.html	2008-02-14 16:13:41.000000000 -0700
+++ lammps-15Feb08/doc/communicate.html	2008-02-15 12:09:18.000000000 -0700
@@ -34,7 +34,8 @@
 </P>
 <P>This command sets the style of inter-processor communication that
 occurs each timestep as atom coordinates and other properties are
-exchanged between neighboring processors.
+exchanged between neighboring processors and stored as properties of
+ghost atoms.
 </P>
 <P>The default style is <I>single</I> which means each processor acquires
 information for ghost atoms that are within a single distance from its
@@ -50,9 +51,11 @@
 simulations of this kind.
 </P>
 <P>The <I>group</I> option will limit communication to atoms in the specified
-group.  This can be useful for certain models where no ghost copies
-are needed for some kinds of particles.  The particles not in the
-specified group will still migrate to new processors as they move.
+group.  This can be useful for models where no ghost atoms are needed
+for some kinds of particles.  All atoms (not just those in the
+specified group) will still migrate to new processors as they move.
+The group specified with this option must also be specified via the
+"atom_modify first" command.
 </P>
 <P><B>Restrictions:</B> none
 </P>
diff -Naur lammps-14Feb08/doc/communicate.txt lammps-15Feb08/doc/communicate.txt
--- lammps-14Feb08/doc/communicate.txt	2008-02-14 16:15:26.000000000 -0700
+++ lammps-15Feb08/doc/communicate.txt	2008-02-15 12:09:18.000000000 -0700
@@ -27,7 +27,8 @@
 
 This command sets the style of inter-processor communication that
 occurs each timestep as atom coordinates and other properties are
-exchanged between neighboring processors.
+exchanged between neighboring processors and stored as properties of
+ghost atoms.
 
 The default style is {single} which means each processor acquires
 information for ghost atoms that are within a single distance from its
@@ -43,9 +44,11 @@
 simulations of this kind.
 
 The {group} option will limit communication to atoms in the specified
-group.  This can be useful for certain models where no ghost copies
-are needed for some kinds of particles.  The particles not in the
-specified group will still migrate to new processors as they move.
+group.  This can be useful for models where no ghost atoms are needed
+for some kinds of particles.  All atoms (not just those in the
+specified group) will still migrate to new processors as they move.
+The group specified with this option must also be specified via the
+"atom_modify first" command.
 
 [Restrictions:] none
 
diff -Naur lammps-14Feb08/doc/neigh_modify.html lammps-15Feb08/doc/neigh_modify.html
--- lammps-14Feb08/doc/neigh_modify.html	2008-02-14 16:13:41.000000000 -0700
+++ lammps-15Feb08/doc/neigh_modify.html	2008-02-15 12:09:18.000000000 -0700
@@ -72,6 +72,13 @@
 command), the <I>every</I> and <I>delay</I> parameters refer to the longest
 (outermost) timestep.
 </P>
+<P>The <I>include</I> option limits the building of pairwise neighbor lists to
+atoms in the specified group.  This can be useful for models where a
+large portion of the simulation is particles that do not interact with
+other particles or with each other via pairwise interactions.  The
+group specified with this option must also be specified via the
+"atom_modify first" command.
+</P>
 <P>The <I>exclude</I> option turns off pairwise interactions between certain
 pairs of atoms, by not including them in the neighbor list.  These are
 sample scenarios where this is useful:
@@ -88,11 +95,6 @@
 body can be turned off to save needless computation.  See the <A HREF = "fix_rigid.html">fix
 rigid</A> command for more details. 
 </UL>
-<P>The <I>include</I> option limits the building of pairwise neighbor lists to
-atoms in the specified group.  This can be useful if a large portion
-of the simulation is particles that do not interact with the remainder
-of the simulation or with each other via pairwise interactions.
-</P>
 <P>The <I>exclude type</I> option turns off the pairwise interaction if one
 atom is of type M and the other of type N.  M can equal N.  The
 <I>exclude group</I> option turns off the interaction if one atom is in the
diff -Naur lammps-14Feb08/doc/neigh_modify.txt lammps-15Feb08/doc/neigh_modify.txt
--- lammps-14Feb08/doc/neigh_modify.txt	2008-02-14 16:13:41.000000000 -0700
+++ lammps-15Feb08/doc/neigh_modify.txt	2008-02-15 12:09:18.000000000 -0700
@@ -66,6 +66,13 @@
 command), the {every} and {delay} parameters refer to the longest
 (outermost) timestep.
 
+The {include} option limits the building of pairwise neighbor lists to
+atoms in the specified group.  This can be useful for models where a
+large portion of the simulation is particles that do not interact with
+other particles or with each other via pairwise interactions.  The
+group specified with this option must also be specified via the
+"atom_modify first" command.
+
 The {exclude} option turns off pairwise interactions between certain
 pairs of atoms, by not including them in the neighbor list.  These are
 sample scenarios where this is useful:
@@ -82,11 +89,6 @@
 body can be turned off to save needless computation.  See the "fix
 rigid"_fix_rigid.html command for more details. :l,ule
 
-The {include} option limits the building of pairwise neighbor lists to
-atoms in the specified group.  This can be useful if a large portion
-of the simulation is particles that do not interact with the remainder
-of the simulation or with each other via pairwise interactions.
-
 The {exclude type} option turns off the pairwise interaction if one
 atom is of type M and the other of type N.  M can equal N.  The
 {exclude group} option turns off the interaction if one atom is in the
diff -Naur lammps-14Feb08/src/ASPHERE/compute_temp_asphere.cpp lammps-15Feb08/src/ASPHERE/compute_temp_asphere.cpp
--- lammps-14Feb08/src/ASPHERE/compute_temp_asphere.cpp	2008-01-02 12:24:46.000000000 -0700
+++ lammps-15Feb08/src/ASPHERE/compute_temp_asphere.cpp	2008-02-15 12:06:53.000000000 -0700
@@ -88,6 +88,7 @@
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
+  if (igroup == atom->firstgroup) nlocal = atom->nfirst;
 
   int itype;
   int rot_dof = 0;
diff -Naur lammps-14Feb08/src/ASPHERE/fix_npt_asphere.cpp lammps-15Feb08/src/ASPHERE/fix_npt_asphere.cpp
--- lammps-14Feb08/src/ASPHERE/fix_npt_asphere.cpp	2008-02-08 12:47:58.000000000 -0700
+++ lammps-15Feb08/src/ASPHERE/fix_npt_asphere.cpp	2008-02-15 12:06:53.000000000 -0700
@@ -91,6 +91,7 @@
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
+  if (igroup == atom->firstgroup) nlocal = atom->nfirst;
 
   double dtfm;
   for (i = 0; i < nlocal; i++) {
@@ -156,6 +157,7 @@
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
+  if (igroup == atom->firstgroup) nlocal = atom->nfirst;
 
   double dtfm;
   for (i = 0; i < nlocal; i++) {
diff -Naur lammps-14Feb08/src/ASPHERE/fix_nve_asphere.cpp lammps-15Feb08/src/ASPHERE/fix_nve_asphere.cpp
--- lammps-14Feb08/src/ASPHERE/fix_nve_asphere.cpp	2008-02-08 12:47:58.000000000 -0700
+++ lammps-15Feb08/src/ASPHERE/fix_nve_asphere.cpp	2008-02-15 12:06:53.000000000 -0700
@@ -76,6 +76,7 @@
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
+  if (igroup == atom->firstgroup) nlocal = atom->nfirst;
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
@@ -113,7 +114,8 @@
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
-  
+  if (igroup == atom->firstgroup) nlocal = atom->nfirst;
+
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       dtfm = dtf / mass[type[i]];
diff -Naur lammps-14Feb08/src/ASPHERE/fix_nvt_asphere.cpp lammps-15Feb08/src/ASPHERE/fix_nvt_asphere.cpp
--- lammps-14Feb08/src/ASPHERE/fix_nvt_asphere.cpp	2008-02-08 12:47:58.000000000 -0700
+++ lammps-15Feb08/src/ASPHERE/fix_nvt_asphere.cpp	2008-02-15 12:06:53.000000000 -0700
@@ -73,6 +73,7 @@
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
+  if (igroup == atom->firstgroup) nlocal = atom->nfirst;
 
   for (int i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit) {
@@ -115,6 +116,7 @@
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
+  if (igroup == atom->firstgroup) nlocal = atom->nfirst;
 
   for (int i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit) {
diff -Naur lammps-14Feb08/src/DIPOLE/fix_nve_dipole.cpp lammps-15Feb08/src/DIPOLE/fix_nve_dipole.cpp
--- lammps-14Feb08/src/DIPOLE/fix_nve_dipole.cpp	2008-02-08 12:47:58.000000000 -0700
+++ lammps-15Feb08/src/DIPOLE/fix_nve_dipole.cpp	2008-02-15 12:06:53.000000000 -0700
@@ -95,6 +95,7 @@
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
+  if (igroup == atom->firstgroup) nlocal = atom->nfirst;
 
   double g[3];
 
@@ -148,6 +149,7 @@
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
+  if (igroup == atom->firstgroup) nlocal = atom->nfirst;
 
   // update v for all particles
   // update omega for all dipoles
diff -Naur lammps-14Feb08/src/GRANULAR/fix_freeze.cpp lammps-15Feb08/src/GRANULAR/fix_freeze.cpp
--- lammps-14Feb08/src/GRANULAR/fix_freeze.cpp	2008-01-09 14:56:57.000000000 -0700
+++ lammps-15Feb08/src/GRANULAR/fix_freeze.cpp	2008-02-15 12:06:53.000000000 -0700
@@ -68,6 +68,7 @@
   double **torque = atom->torque;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
+  if (igroup == atom->firstgroup) nlocal = atom->nfirst;
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
diff -Naur lammps-14Feb08/src/GRANULAR/fix_nve_gran.cpp lammps-15Feb08/src/GRANULAR/fix_nve_gran.cpp
--- lammps-14Feb08/src/GRANULAR/fix_nve_gran.cpp	2008-01-09 14:56:57.000000000 -0700
+++ lammps-15Feb08/src/GRANULAR/fix_nve_gran.cpp	2008-02-15 12:06:53.000000000 -0700
@@ -75,6 +75,7 @@
   double *radius = atom->radius;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
+  if (igroup == atom->firstgroup) nlocal = atom->nfirst;
 
   for (int i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit) {
@@ -111,6 +112,7 @@
   double *radius = atom->radius;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
+  if (igroup == atom->firstgroup) nlocal = atom->nfirst;
 
   for (int i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit) {
diff -Naur lammps-14Feb08/src/atom.cpp lammps-15Feb08/src/atom.cpp
--- lammps-14Feb08/src/atom.cpp	2007-12-07 07:56:45.000000000 -0700
+++ lammps-15Feb08/src/atom.cpp	2008-02-15 12:06:53.000000000 -0700
@@ -52,6 +52,8 @@
   nbonds = nangles = ndihedrals = nimpropers = 0;
   bond_per_atom = angle_per_atom = dihedral_per_atom = improper_per_atom = 0;
 
+  firstgroupname = NULL;
+
   // initialize atom arrays
   // customize by adding new array
 
@@ -136,6 +138,7 @@
 {
   delete [] atom_style;
   delete avec;
+  delete [] firstgroupname;
 
   // delete atom arrays
   // customize by adding new array
@@ -273,6 +276,14 @@
   check_shape();
   check_dipole();
 
+  // setup of firstgroup
+
+  if (firstgroupname) {
+    firstgroup = group->find(firstgroupname);
+    if (firstgroup < 0)
+      error->all("Could not find atom_modify first group ID");
+  } else firstgroup = -1;
+
   // init sub-style
 
   avec->init();
@@ -310,6 +321,15 @@
       else if (strcmp(arg[iarg+1],"hash") == 0) map_style = 2;
       else error->all("Illegal atom_modify command");
       iarg += 2;
+    } else if (strcmp(arg[iarg],"first") == 0) {
+      if (iarg+2 > narg) error->all("Illegal atom_modify command");
+      if (strcmp(arg[iarg+1],"all") == 0) delete [] firstgroupname;
+      else {
+	int n = strlen(arg[iarg+1]) + 1;
+	firstgroupname = new char[n];
+	strcpy(firstgroupname,arg[iarg+1]);
+      }
+      iarg += 2;
     } else error->all("Illegal atom_modify command");
   }
 }
@@ -1206,6 +1226,36 @@
 }
 
 /* ----------------------------------------------------------------------
+   reorder owned atoms so those in firstgroup appear first
+   called by comm->exchange() if atom_modify first group is set
+   only owned atoms exist at this point, no ghost atoms
+------------------------------------------------------------------------- */
+
+void Atom::first_reorder()
+{
+  // insure there is one extra atom location at end of arrays for swaps
+
+  if (nlocal == nmax) avec->grow(0);
+
+  // loop over owned atoms
+  // nfirst = index of first atom not in firstgroup
+  // when find firstgroup atom out of place, swap it with atom nfirst
+
+  int bitmask = group->bitmask[firstgroup];
+  nfirst = 0;
+  while (nfirst < nlocal && mask[nfirst] & bitmask) nfirst++;
+
+  for (int i = 0; i < nlocal; i++) {
+    if (mask[i] & bitmask && i > nfirst) {
+      avec->copy(i,nlocal);
+      avec->copy(nfirst,i);
+      avec->copy(nlocal,nfirst);
+      while (nfirst < nlocal && mask[nfirst] & bitmask) nfirst++;
+    }
+  }
+}
+
+/* ----------------------------------------------------------------------
    register a callback to a fix so it can manage atom-based arrays
    happens when fix is created
    flag = 0 for grow, 1 for restart
diff -Naur lammps-14Feb08/src/atom.h lammps-15Feb08/src/atom.h
--- lammps-14Feb08/src/atom.h	2007-12-07 07:56:45.000000000 -0700
+++ lammps-15Feb08/src/atom.h	2008-02-15 12:06:53.000000000 -0700
@@ -35,6 +35,10 @@
   int nbonds,nangles,ndihedrals,nimpropers;
   int bond_per_atom,angle_per_atom,dihedral_per_atom,improper_per_atom;
 
+  int firstgroup;               // store atoms in this group first, -1 if unset
+  int nfirst;                   // # of atoms in first group on this proc
+  char *firstgroupname;         // group-ID to store first, NULL if unset
+
   // per-atom arrays
   // customize by adding new array
 
@@ -132,6 +136,8 @@
   void set_dipole(double *);
   void check_dipole();
 
+  void first_reorder();
+
   void add_callback(int);
   void delete_callback(const char *, int);
   void update_callback(int);
diff -Naur lammps-14Feb08/src/comm.cpp lammps-15Feb08/src/comm.cpp
--- lammps-14Feb08/src/comm.cpp	2008-02-14 16:05:04.000000000 -0700
+++ lammps-15Feb08/src/comm.cpp	2008-02-15 12:06:53.000000000 -0700
@@ -58,7 +58,7 @@
   user_procgrid[0] = user_procgrid[1] = user_procgrid[2] = 0;
   grid2proc = NULL;
 
-  igroup = 0;
+  bordergroup = 0;
   style = SINGLE;
   multilo = multihi = NULL;
   cutghostmulti = NULL;
@@ -172,7 +172,6 @@
 {
   triclinic = domain->triclinic;
   map_style = atom->map_style;
-  groupbit = group->bitmask[igroup];
 
   // comm_only = 1 if only x,f are exchanged in forward/reverse comm
 
@@ -488,8 +487,7 @@
 }
 
 /* ----------------------------------------------------------------------
-   exchange:
-   move atoms to correct processors
+   exchange: move atoms to correct processors
    atoms exchanged with all 6 stencil neighbors
    send out atoms that have left my box, receive ones entering my box
    atoms will be lost if not inside some proc's box
@@ -591,11 +589,12 @@
       else m += static_cast<int> (buf[m]);
     }
   }
+
+  if (atom->firstgroupname) atom->first_reorder();
 }
 
 /* ----------------------------------------------------------------------
-   borders:
-   make lists of nearby atoms to send to neighboring procs at every timestep
+   borders: list nearby atoms to send to neighboring procs at every timestep
    one list is created for every swap that will be made
    as list is made, actually do swaps
    this does equivalent of a communicate (so don't need to explicitly
@@ -606,9 +605,10 @@
 
 void Comm::borders()
 {
-  int i,n,itype,iswap,dim,ineed,maxneed,nsend,nrecv,nfirst,nlast,smax,rmax;
+  int i,n,itype,iswap,dim,ineed,maxneed,smax,rmax;
+  int nsend,nrecv,nfirst,nlast,ngroup;
   double lo,hi;
-  int *type,*mask;
+  int *type;
   double **x;
   double *buf,*mlo,*mhi;
   MPI_Request request;
@@ -652,37 +652,51 @@
 
       nsend = 0;
 
-      // SINGLE vs MULTI, all atoms versus only atoms in group
+      // find send atoms according to SINGLE vs MULTI
+      // all atoms eligible versus atoms in bordergroup
+      // only need to limit loop to bordergroup for first sends (ineed < 2)
+      // on these sends, break loop in two: owned (in group) and ghost
 
-      if (igroup) {
-	mask = atom->mask;
+      if (!bordergroup || ineed >= 2) {
 	if (style == SINGLE) {
 	  for (i = nfirst; i < nlast; i++)
-	    if (mask[i] & groupbit) {
-	      if (x[i][dim] >= lo && x[i][dim] <= hi) {
-		if (nsend == maxsendlist[iswap]) grow_list(iswap,nsend);
-		sendlist[iswap][nsend++] = i;
-	      }
+	    if (x[i][dim] >= lo && x[i][dim] <= hi) {
+	      if (nsend == maxsendlist[iswap]) grow_list(iswap,nsend);
+	      sendlist[iswap][nsend++] = i;
 	    }
 	} else {
-	  for (i = nfirst; i < nlast; i++)
-	    if (mask[i] & groupbit) {
-	      itype = type[i];
-	      if (x[i][dim] >= mlo[itype] && x[i][dim] <= mhi[itype]) {
-		if (nsend == maxsendlist[iswap]) grow_list(iswap,nsend);
-		sendlist[iswap][nsend++] = i;
-	      }
+	  for (i = nfirst; i < nlast; i++) {
+	    itype = type[i];
+	    if (x[i][dim] >= mlo[itype] && x[i][dim] <= mhi[itype]) {
+	      if (nsend == maxsendlist[iswap]) grow_list(iswap,nsend);
+	      sendlist[iswap][nsend++] = i;
 	    }
+	  }
 	}
+
       } else {
 	if (style == SINGLE) {
-	  for (i = nfirst; i < nlast; i++)
+	  ngroup = atom->nfirst;
+	  for (i = 0; i < ngroup; i++)
+	    if (x[i][dim] >= lo && x[i][dim] <= hi) {
+	      if (nsend == maxsendlist[iswap]) grow_list(iswap,nsend);
+	      sendlist[iswap][nsend++] = i;
+	    }
+	  for (i = atom->nlocal; i < nlast; i++)
 	    if (x[i][dim] >= lo && x[i][dim] <= hi) {
 	      if (nsend == maxsendlist[iswap]) grow_list(iswap,nsend);
 	      sendlist[iswap][nsend++] = i;
 	    }
 	} else {
-	  for (i = nfirst; i < nlast; i++) {
+	  ngroup = atom->nfirst;
+	  for (i = 0; i < ngroup; i++) {
+	    itype = type[i];
+	    if (x[i][dim] >= mlo[itype] && x[i][dim] <= mhi[itype]) {
+	      if (nsend == maxsendlist[iswap]) grow_list(iswap,nsend);
+	      sendlist[iswap][nsend++] = i;
+	    }
+	  }
+	  for (i = atom->nlocal; i < nlast; i++) {
 	    itype = type[i];
 	    if (x[i][dim] >= mlo[itype] && x[i][dim] <= mhi[itype]) {
 	      if (nsend == maxsendlist[iswap]) grow_list(iswap,nsend);
@@ -1504,9 +1518,12 @@
   while (iarg < narg) {
     if (strcmp(arg[iarg],"group") == 0) {
       if (iarg+2 > narg) error->all("Illegal communicate command");
-      igroup = group->find(arg[iarg+1]);
-      if (igroup < 0)
+      bordergroup = group->find(arg[iarg+1]);
+      if (bordergroup < 0)
 	error->all("Invalid group ID in communicate command");
+      if (bordergroup && (atom->firstgroupname == NULL || 
+			  strcmp(arg[iarg+1],atom->firstgroupname) != 0))
+	error->all("Communicate group != atom_modify first group");
       iarg += 2;
     } else error->all("Illegal communicate command");
   }
diff -Naur lammps-14Feb08/src/comm.h lammps-15Feb08/src/comm.h
--- lammps-14Feb08/src/comm.h	2008-02-14 16:05:04.000000000 -0700
+++ lammps-15Feb08/src/comm.h	2008-02-15 12:06:53.000000000 -0700
@@ -71,7 +71,7 @@
   int comm_x_only,comm_f_only;      // 1 if only exchange x,f in for/rev comm
   int map_style;                    // non-0 if global->local mapping is done
   int ***grid2proc;                 // which proc owns i,j,k loc in 3d grid
-  int igroup,groupbit;              // only communicate this group
+  int bordergroup;                  // only communicate this group in borders
 
   int *firstrecv;                   // where to put 1st recv atom in each swap
   int **sendlist;                   // list of atoms to send in each swap
diff -Naur lammps-14Feb08/src/fix_enforce2d.cpp lammps-15Feb08/src/fix_enforce2d.cpp
--- lammps-14Feb08/src/fix_enforce2d.cpp	2008-01-31 08:18:01.000000000 -0700
+++ lammps-15Feb08/src/fix_enforce2d.cpp	2008-02-15 12:06:53.000000000 -0700
@@ -79,6 +79,7 @@
   double **f = atom->f;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
+  if (igroup == atom->firstgroup) nlocal = atom->nfirst;
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
diff -Naur lammps-14Feb08/src/fix_npt.cpp lammps-15Feb08/src/fix_npt.cpp
--- lammps-14Feb08/src/fix_npt.cpp	2008-01-09 14:56:57.000000000 -0700
+++ lammps-15Feb08/src/fix_npt.cpp	2008-02-15 12:06:53.000000000 -0700
@@ -374,6 +374,7 @@
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
+  if (igroup == atom->firstgroup) nlocal = atom->nfirst;
 
   double dtfm;
   for (i = 0; i < nlocal; i++) {
@@ -422,6 +423,7 @@
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
+  if (igroup == atom->firstgroup) nlocal = atom->nfirst;
 
   double dtfm;
   for (i = 0; i < nlocal; i++) {
@@ -499,6 +501,7 @@
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
+  if (igroup == atom->firstgroup) nlocal = atom->nfirst;
 
   // outermost level - update eta_dot and omega_dot, apply to v, remap box
   // all other levels - NVE update of v
@@ -604,6 +607,7 @@
     int *type = atom->type;
     int *mask = atom->mask;
     int nlocal = atom->nlocal;
+    if (igroup == atom->firstgroup) nlocal = atom->nfirst;
 
     for (int i = 0; i < nlocal; i++) {
       if (mask[i] & groupbit) {
diff -Naur lammps-14Feb08/src/fix_nve.cpp lammps-15Feb08/src/fix_nve.cpp
--- lammps-14Feb08/src/fix_nve.cpp	2008-01-09 14:56:57.000000000 -0700
+++ lammps-15Feb08/src/fix_nve.cpp	2008-02-15 12:06:53.000000000 -0700
@@ -70,6 +70,7 @@
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
+  if (igroup == atom->firstgroup) nlocal = atom->nfirst;
 
   if (mass) {
     for (int i = 0; i < nlocal; i++) {
@@ -112,6 +113,7 @@
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
+  if (igroup == atom->firstgroup) nlocal = atom->nfirst;
 
   if (mass) {
     for (int i = 0; i < nlocal; i++) {
diff -Naur lammps-14Feb08/src/fix_nve_limit.cpp lammps-15Feb08/src/fix_nve_limit.cpp
--- lammps-14Feb08/src/fix_nve_limit.cpp	2008-01-09 14:56:57.000000000 -0700
+++ lammps-15Feb08/src/fix_nve_limit.cpp	2008-02-15 12:06:53.000000000 -0700
@@ -79,6 +79,7 @@
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
+  if (igroup == atom->firstgroup) nlocal = atom->nfirst;
 
   if (mass) {
     for (int i = 0; i < nlocal; i++) {
@@ -141,6 +142,7 @@
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
+  if (igroup == atom->firstgroup) nlocal = atom->nfirst;
 
   if (mass) {
     for (int i = 0; i < nlocal; i++) {
diff -Naur lammps-14Feb08/src/fix_nve_noforce.cpp lammps-15Feb08/src/fix_nve_noforce.cpp
--- lammps-14Feb08/src/fix_nve_noforce.cpp	2008-01-09 14:56:57.000000000 -0700
+++ lammps-15Feb08/src/fix_nve_noforce.cpp	2008-02-15 12:06:53.000000000 -0700
@@ -57,6 +57,7 @@
   double **v = atom->v;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
+  if (igroup == atom->firstgroup) nlocal = atom->nfirst;
 
   for (int i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit) {
diff -Naur lammps-14Feb08/src/fix_nvt.cpp lammps-15Feb08/src/fix_nvt.cpp
--- lammps-14Feb08/src/fix_nvt.cpp	2008-01-09 14:56:57.000000000 -0700
+++ lammps-15Feb08/src/fix_nvt.cpp	2008-02-15 12:06:53.000000000 -0700
@@ -167,6 +167,7 @@
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
+  if (igroup == atom->firstgroup) nlocal = atom->nfirst;
 
   for (int i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit) {
@@ -195,6 +196,7 @@
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
+  if (igroup == atom->firstgroup) nlocal = atom->nfirst;
 
   for (int i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit) {
@@ -238,6 +240,7 @@
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
+  if (igroup == atom->firstgroup) nlocal = atom->nfirst;
 
   // outermost level - update eta_dot and apply to v
   // all other levels - NVE update of v
@@ -305,6 +308,7 @@
     int *type = atom->type;
     int *mask = atom->mask;
     int nlocal = atom->nlocal;
+    if (igroup == atom->firstgroup) nlocal = atom->nfirst;
 
     for (int i = 0; i < nlocal; i++) {
       if (mask[i] & groupbit) {
diff -Naur lammps-14Feb08/src/fix_nvt_sllod.cpp lammps-15Feb08/src/fix_nvt_sllod.cpp
--- lammps-14Feb08/src/fix_nvt_sllod.cpp	2008-01-09 14:56:57.000000000 -0700
+++ lammps-15Feb08/src/fix_nvt_sllod.cpp	2008-02-15 12:06:53.000000000 -0700
@@ -91,6 +91,7 @@
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
+  if (igroup == atom->firstgroup) nlocal = atom->nfirst;
 
   double *h_rate = domain->h_rate;
   double *h_ratelo = domain->h_ratelo;
@@ -146,6 +147,7 @@
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
+  if (igroup == atom->firstgroup) nlocal = atom->nfirst;
 
   double *h_rate = domain->h_rate;
   double *h_ratelo = domain->h_ratelo;
@@ -211,6 +213,7 @@
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
+  if (igroup == atom->firstgroup) nlocal = atom->nfirst;
 
   // outermost level - update eta_dot and apply to v
   // all other levels - NVE update of v
diff -Naur lammps-14Feb08/src/neigh_derive.cpp lammps-15Feb08/src/neigh_derive.cpp
--- lammps-14Feb08/src/neigh_derive.cpp	2008-02-14 16:05:04.000000000 -0700
+++ lammps-15Feb08/src/neigh_derive.cpp	2008-02-15 12:06:53.000000000 -0700
@@ -93,7 +93,7 @@
 
   double **x = atom->x;
   int nlocal = atom->nlocal;
-  int nall = atom->nlocal + atom->nghost;
+  int nall = nlocal + atom->nghost;
 
   int *ilist = list->ilist;
   int *numneigh = list->numneigh;
diff -Naur lammps-14Feb08/src/neigh_full.cpp lammps-15Feb08/src/neigh_full.cpp
--- lammps-14Feb08/src/neigh_full.cpp	2008-02-14 16:05:04.000000000 -0700
+++ lammps-15Feb08/src/neigh_full.cpp	2008-02-15 12:06:53.000000000 -0700
@@ -14,6 +14,7 @@
 #include "neighbor.h"
 #include "neigh_list.h"
 #include "atom.h"
+#include "group.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
@@ -25,7 +26,7 @@
 
 void Neighbor::full_nsq(NeighList *list)
 {
-  int i,j,n,itype,jtype,which;
+  int i,j,n,itype,jtype,which,bitmask;
   double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
   int *neighptr;
 
@@ -34,8 +35,12 @@
   int *mask = atom->mask;
   int *molecule = atom->molecule;
   int nlocal = atom->nlocal;
-  int nall = atom->nlocal + atom->nghost;
+  int nall = nlocal + atom->nghost;
   int molecular = atom->molecular;
+  if (include_group) {
+    nlocal = atom->nfirst;
+    bitmask = group->bitmask[include_group];
+  }
 
   int *ilist = list->ilist;
   int *numneigh = list->numneigh;
@@ -47,7 +52,6 @@
   int npnt = 0;
 
   for (i = 0; i < nlocal; i++) {
-    if (include_group && !(mask[i] & include_groupbit)) continue;
 
     if (pgsize - npnt < oneatom) {
       npnt = 0;
@@ -67,8 +71,8 @@
     // skip i = j
 
     for (j = 0; j < nall; j++) {
+      if (include_group && !(mask[j] & bitmask)) continue;
       if (i == j) continue;
-
       jtype = type[j];
       if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
 
@@ -117,8 +121,9 @@
   int *mask = atom->mask;
   int *molecule = atom->molecule;
   int nlocal = atom->nlocal;
-  int nall = atom->nlocal + atom->nghost;
+  int nall = nlocal + atom->nghost;
   int molecular = atom->molecular;
+  if (include_group) nlocal = atom->nfirst;
 
   int *ilist = list->ilist;
   int *numneigh = list->numneigh;
@@ -132,7 +137,6 @@
   int npnt = 0;
 
   for (i = 0; i < nlocal; i++) {
-    if (include_group && !(mask[i] & include_groupbit)) continue;
 
     if (pgsize - npnt < oneatom) {
       npnt = 0;
@@ -209,8 +213,9 @@
   int *mask = atom->mask;
   int *molecule = atom->molecule;
   int nlocal = atom->nlocal;
-  int nall = atom->nlocal + atom->nghost;
+  int nall = nlocal + atom->nghost;
   int molecular = atom->molecular;
+  if (include_group) nlocal = atom->nfirst;
 
   int *ilist = list->ilist;
   int *numneigh = list->numneigh;
@@ -225,7 +230,6 @@
   int npnt = 0;
 
   for (i = 0; i < nlocal; i++) {
-    if (include_group && !(mask[i] & include_groupbit)) continue;
 
     if (pgsize - npnt < oneatom) {
       npnt = 0;
diff -Naur lammps-14Feb08/src/neigh_gran.cpp lammps-15Feb08/src/neigh_gran.cpp
--- lammps-14Feb08/src/neigh_gran.cpp	2008-02-14 16:05:04.000000000 -0700
+++ lammps-15Feb08/src/neigh_gran.cpp	2008-02-15 12:06:53.000000000 -0700
@@ -14,6 +14,7 @@
 #include "neighbor.h"
 #include "neigh_list.h"
 #include "atom.h"
+#include "group.h"
 #include "fix_shear_history.h"
 #include "error.h"
 
@@ -29,7 +30,7 @@
 
 void Neighbor::granular_nsq_no_newton(NeighList *list)
 {
-  int i,j,m,n,nn;
+  int i,j,m,n,nn,bitmask;
   double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
   double radi,radsum,cutsq;
   int *neighptr,*touchptr;
@@ -50,7 +51,11 @@
   int *mask = atom->mask;
   int *molecule = atom->molecule;
   int nlocal = atom->nlocal;
-  int nall = atom->nlocal + atom->nghost;
+  int nall = nlocal + atom->nghost;
+  if (include_group) {
+    nlocal = atom->nfirst;
+    bitmask = group->bitmask[include_group];
+  }
 
   int *ilist = list->ilist;
   int *numneigh = list->numneigh;
@@ -74,7 +79,6 @@
   int npnt = 0;
 
   for (i = 0; i < nlocal; i++) {
-    if (include_group && !(mask[i] & include_groupbit)) continue;
 
     if (pgsize - npnt < oneatom) {
       npnt = 0;
@@ -104,6 +108,7 @@
     // loop over remaining atoms, owned and ghost
 
     for (j = i+1; j < nall; j++) {
+      if (include_group && !(mask[j] & bitmask)) continue;
       if (exclude && exclusion(i,j,type[i],type[j],mask,molecule)) continue;
 
       delx = xtmp - x[j][0];
@@ -169,7 +174,7 @@
 
 void Neighbor::granular_nsq_newton(NeighList *list)
 {
-  int i,j,n,itag,jtag;
+  int i,j,n,itag,jtag,bitmask;
   double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
   double radi,radsum,cutsq;
   int *neighptr;
@@ -181,7 +186,11 @@
   int *mask = atom->mask;
   int *molecule = atom->molecule;
   int nlocal = atom->nlocal;
-  int nall = atom->nlocal + atom->nghost;
+  int nall = nlocal + atom->nghost;
+  if (include_group) {
+    nlocal = atom->nfirst;
+    bitmask = group->bitmask[include_group];
+  }
 
   int *ilist = list->ilist;
   int *numneigh = list->numneigh;
@@ -193,7 +202,6 @@
   int npnt = 0;
 
   for (i = 0; i < nlocal; i++) {
-    if (include_group && !(mask[i] & include_groupbit)) continue;
 
     if (pgsize - npnt < oneatom) {
       npnt = 0;
@@ -213,6 +221,8 @@
     // loop over remaining atoms, owned and ghost
 
     for (j = i+1; j < nall; j++) {
+      if (include_group && !(mask[j] & bitmask)) continue;
+
       if (j >= nlocal) {
 	jtag = tag[j];
 	if (itag > jtag) {
@@ -288,6 +298,7 @@
   int *mask = atom->mask;
   int *molecule = atom->molecule;
   int nlocal = atom->nlocal;
+  if (include_group) nlocal = atom->nfirst;
 
   int *ilist = list->ilist;
   int *numneigh = list->numneigh;
@@ -313,7 +324,6 @@
   int npnt = 0;
 
   for (i = 0; i < nlocal; i++) {
-    if (include_group && !(mask[i] & include_groupbit)) continue;
 
     if (pgsize - npnt < oneatom) {
       npnt = 0;
@@ -431,6 +441,7 @@
   int *mask = atom->mask;
   int *molecule = atom->molecule;
   int nlocal = atom->nlocal;
+  if (include_group) nlocal = atom->nfirst;
 
   int *ilist = list->ilist;
   int *numneigh = list->numneigh;
@@ -444,7 +455,6 @@
   int npnt = 0;
 
   for (i = 0; i < nlocal; i++) {
-    if (include_group && !(mask[i] & include_groupbit)) continue;
 
     if (pgsize - npnt < oneatom) {
       npnt = 0;
@@ -538,6 +548,7 @@
   int *mask = atom->mask;
   int *molecule = atom->molecule;
   int nlocal = atom->nlocal;
+  if (include_group) nlocal = atom->nfirst;
 
   int *ilist = list->ilist;
   int *numneigh = list->numneigh;
@@ -551,7 +562,6 @@
   int npnt = 0;
 
   for (i = 0; i < nlocal; i++) {
-    if (include_group && !(mask[i] & include_groupbit)) continue;
 
     if (pgsize - npnt < oneatom) {
       npnt = 0;
diff -Naur lammps-14Feb08/src/neigh_half_bin.cpp lammps-15Feb08/src/neigh_half_bin.cpp
--- lammps-14Feb08/src/neigh_half_bin.cpp	2008-02-14 16:05:04.000000000 -0700
+++ lammps-15Feb08/src/neigh_half_bin.cpp	2008-02-15 12:06:53.000000000 -0700
@@ -42,7 +42,8 @@
   int *mask = atom->mask;
   int *molecule = atom->molecule;
   int nlocal = atom->nlocal;
-  int nall = atom->nlocal + atom->nghost;
+  int nall = nlocal + atom->nghost;
+  if (include_group) nlocal = atom->nfirst;
   int molecular = atom->molecular;
 
   int *ilist = list->ilist;
@@ -57,7 +58,6 @@
   int npnt = 0;
 
   for (i = 0; i < nlocal; i++) {
-    if (include_group && !(mask[i] & include_groupbit)) continue;
 
     if (pgsize - npnt < oneatom) {
       npnt = 0;
@@ -135,8 +135,9 @@
   int *mask = atom->mask;
   int *molecule = atom->molecule;
   int nlocal = atom->nlocal;
-  int nall = atom->nlocal + atom->nghost;
+  int nall = nlocal + atom->nghost;
   int molecular = atom->molecular;
+  if (include_group) nlocal = atom->nfirst;
 
   int *ilist = list->ilist;
   int *numneigh = list->numneigh;
@@ -150,7 +151,6 @@
   int npnt = 0;
 
   for (i = 0; i < nlocal; i++) {
-    if (include_group && !(mask[i] & include_groupbit)) continue;
 
     if (pgsize - npnt < oneatom) {
       npnt = 0;
@@ -249,8 +249,9 @@
   int *mask = atom->mask;
   int *molecule = atom->molecule;
   int nlocal = atom->nlocal;
-  int nall = atom->nlocal + atom->nghost;
+  int nall = nlocal + atom->nghost;
   int molecular = atom->molecular;
+  if (include_group) nlocal = atom->nfirst;
 
   int *ilist = list->ilist;
   int *numneigh = list->numneigh;
@@ -264,7 +265,6 @@
   int npnt = 0;
 
   for (i = 0; i < nlocal; i++) {
-    if (include_group && !(mask[i] & include_groupbit)) continue;
 
     if (pgsize - npnt < oneatom) {
       npnt = 0;
diff -Naur lammps-14Feb08/src/neigh_half_multi.cpp lammps-15Feb08/src/neigh_half_multi.cpp
--- lammps-14Feb08/src/neigh_half_multi.cpp	2008-02-14 16:05:04.000000000 -0700
+++ lammps-15Feb08/src/neigh_half_multi.cpp	2008-02-15 12:06:53.000000000 -0700
@@ -44,8 +44,9 @@
   int *mask = atom->mask;
   int *molecule = atom->molecule;
   int nlocal = atom->nlocal;
-  int nall = atom->nlocal + atom->nghost;
+  int nall = nlocal + atom->nghost;
   int molecular = atom->molecular;
+  if (include_group) nlocal = atom->nfirst;
 
   int *ilist = list->ilist;
   int *numneigh = list->numneigh;
@@ -60,7 +61,6 @@
   int npnt = 0;
 
   for (i = 0; i < nlocal; i++) {
-    if (include_group && !(mask[i] & include_groupbit)) continue;
 
     if (pgsize - npnt < oneatom) {
       npnt = 0;
@@ -145,8 +145,9 @@
   int *mask = atom->mask;
   int *molecule = atom->molecule;
   int nlocal = atom->nlocal;
-  int nall = atom->nlocal + atom->nghost;
+  int nall = nlocal + atom->nghost;
   int molecular = atom->molecular;
+  if (include_group) nlocal = atom->nfirst;
 
   int *ilist = list->ilist;
   int *numneigh = list->numneigh;
@@ -161,7 +162,6 @@
   int npnt = 0;
 
   for (i = 0; i < nlocal; i++) {
-    if (include_group && !(mask[i] & include_groupbit)) continue;
 
     if (pgsize - npnt < oneatom) {
       npnt = 0;
@@ -269,8 +269,9 @@
   int *mask = atom->mask;
   int *molecule = atom->molecule;
   int nlocal = atom->nlocal;
-  int nall = atom->nlocal + atom->nghost;
+  int nall = nlocal + atom->nghost;
   int molecular = atom->molecular;
+  if (include_group) nlocal = atom->nfirst;
 
   int *ilist = list->ilist;
   int *numneigh = list->numneigh;
@@ -285,7 +286,6 @@
   int npnt = 0;
 
   for (i = 0; i < nlocal; i++) {
-    if (include_group && !(mask[i] & include_groupbit)) continue;
 
     if (pgsize - npnt < oneatom) {
       npnt = 0;
diff -Naur lammps-14Feb08/src/neigh_half_nsq.cpp lammps-15Feb08/src/neigh_half_nsq.cpp
--- lammps-14Feb08/src/neigh_half_nsq.cpp	2008-02-14 16:05:04.000000000 -0700
+++ lammps-15Feb08/src/neigh_half_nsq.cpp	2008-02-15 12:06:53.000000000 -0700
@@ -14,6 +14,7 @@
 #include "neighbor.h"
 #include "neigh_list.h"
 #include "atom.h"
+#include "group.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
@@ -26,7 +27,7 @@
 
 void Neighbor::half_nsq_no_newton(NeighList *list)
 {
-  int i,j,n,itype,jtype,which;
+  int i,j,n,itype,jtype,which,bitmask;
   double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
   int *neighptr;
 
@@ -35,8 +36,12 @@
   int *mask = atom->mask;
   int *molecule = atom->molecule;
   int nlocal = atom->nlocal;
-  int nall = atom->nlocal + atom->nghost;
+  int nall = nlocal + atom->nghost;
   int molecular = atom->molecular;
+  if (include_group) {
+    nlocal = atom->nfirst;
+    bitmask = group->bitmask[include_group];
+  }
 
   int *ilist = list->ilist;
   int *numneigh = list->numneigh;
@@ -48,7 +53,6 @@
   int npnt = 0;
 
   for (i = 0; i < nlocal; i++) {
-    if (include_group && !(mask[i] & include_groupbit)) continue;
 
     if (pgsize - npnt < oneatom) {
       npnt = 0;
@@ -67,6 +71,7 @@
     // loop over remaining atoms, owned and ghost
 
     for (j = i+1; j < nall; j++) {
+      if (include_group && !(mask[j] & bitmask)) continue;
       jtype = type[j];
       if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
 
@@ -102,7 +107,7 @@
 
 void Neighbor::half_nsq_newton(NeighList *list)
 {
-  int i,j,n,itype,jtype,itag,jtag,which;
+  int i,j,n,itype,jtype,itag,jtag,which,bitmask;
   double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
   int *neighptr;
 
@@ -112,8 +117,12 @@
   int *mask = atom->mask;
   int *molecule = atom->molecule;
   int nlocal = atom->nlocal;
-  int nall = atom->nlocal + atom->nghost;
+  int nall = nlocal + atom->nghost;
   int molecular = atom->molecular;
+  if (include_group) {
+    nlocal = atom->nfirst;
+    bitmask = group->bitmask[include_group];
+  }
 
   int *ilist = list->ilist;
   int *numneigh = list->numneigh;
@@ -125,7 +134,6 @@
   int npnt = 0;
 
   for (i = 0; i < nlocal; i++) {
-    if (include_group && !(mask[i] & include_groupbit)) continue;
 
     if (pgsize - npnt < oneatom) {
       npnt = 0;
@@ -146,6 +154,8 @@
     // itag = jtag is possible for long cutoffs that include images of self
 
     for (j = i+1; j < nall; j++) {
+      if (include_group && !(mask[j] & bitmask)) continue;
+
       if (j >= nlocal) {
 	jtag = tag[j];
 	if (itag > jtag) {
diff -Naur lammps-14Feb08/src/neigh_respa.cpp lammps-15Feb08/src/neigh_respa.cpp
--- lammps-14Feb08/src/neigh_respa.cpp	2008-02-14 16:05:04.000000000 -0700
+++ lammps-15Feb08/src/neigh_respa.cpp	2008-02-15 12:06:53.000000000 -0700
@@ -14,6 +14,7 @@
 #include "neighbor.h"
 #include "neigh_list.h"
 #include "atom.h"
+#include "group.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
@@ -27,7 +28,7 @@
 
 void Neighbor::respa_nsq_no_newton(NeighList *list)
 {
-  int i,j,n,itype,jtype,which,n_inner,n_middle;
+  int i,j,n,itype,jtype,which,n_inner,n_middle,bitmask;
   double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
   int *neighptr,*neighptr_inner,*neighptr_middle;
 
@@ -36,8 +37,12 @@
   int *mask = atom->mask;
   int *molecule = atom->molecule;
   int nlocal = atom->nlocal;
-  int nall = atom->nlocal + atom->nghost;
+  int nall = nlocal + atom->nghost;
   int molecular = atom->molecular;
+  if (include_group) {
+    nlocal = atom->nfirst;
+    bitmask = group->bitmask[include_group];
+  }
 
   int *ilist = list->ilist;
   int *numneigh = list->numneigh;
@@ -68,7 +73,6 @@
   int npnt_middle = 0;
 
   for (i = 0; i < nlocal; i++) {
-    if (include_group && !(mask[i] & include_groupbit)) continue;
 
     if (pgsize - npnt < oneatom) {
       npnt = 0;
@@ -106,6 +110,7 @@
     // loop over remaining atoms, owned and ghost
 
     for (j = i+1; j < nall; j++) {
+      if (include_group && !(mask[j] & bitmask)) continue;
       jtype = type[j];
       if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
 
@@ -167,7 +172,7 @@
 
 void Neighbor::respa_nsq_newton(NeighList *list)
 {
-  int i,j,n,itype,jtype,itag,jtag,which,n_inner,n_middle;
+  int i,j,n,itype,jtype,itag,jtag,which,n_inner,n_middle,bitmask;
   double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
   int *neighptr,*neighptr_inner,*neighptr_middle;
 
@@ -177,8 +182,12 @@
   int *mask = atom->mask;
   int *molecule = atom->molecule;
   int nlocal = atom->nlocal;
-  int nall = atom->nlocal + atom->nghost;
+  int nall = nlocal + atom->nghost;
   int molecular = atom->molecular;
+  if (include_group) {
+    nlocal = atom->nfirst;
+    bitmask = group->bitmask[include_group];
+  }
 
   int *ilist = list->ilist;
   int *numneigh = list->numneigh;
@@ -209,7 +218,6 @@
   int npnt_middle = 0;
 
   for (i = 0; i < nlocal; i++) {
-    if (include_group && !(mask[i] & include_groupbit)) continue;
 
     if (pgsize - npnt < oneatom) {
       npnt = 0;
@@ -248,6 +256,8 @@
     // loop over remaining atoms, owned and ghost
 
     for (j = i+1; j < nall; j++) {
+      if (include_group && !(mask[j] & bitmask)) continue;
+
       if (j >= nlocal) {
 	jtag = tag[j];
 	if (itag > jtag) {
@@ -339,8 +349,9 @@
   int *mask = atom->mask;
   int *molecule = atom->molecule;
   int nlocal = atom->nlocal;
-  int nall = atom->nlocal + atom->nghost;
+  int nall = nlocal + atom->nghost;
   int molecular = atom->molecular;
+  if (include_group) nlocal = atom->nfirst;
 
   int *ilist = list->ilist;
   int *numneigh = list->numneigh;
@@ -373,7 +384,6 @@
   int npnt_middle = 0;
 
   for (i = 0; i < nlocal; i++) {
-    if (include_group && !(mask[i] & include_groupbit)) continue;
 
     if (pgsize - npnt < oneatom) {
       npnt = 0;
@@ -495,8 +505,9 @@
   int *mask = atom->mask;
   int *molecule = atom->molecule;
   int nlocal = atom->nlocal;
-  int nall = atom->nlocal + atom->nghost;
+  int nall = nlocal + atom->nghost;
   int molecular = atom->molecular;
+  if (include_group) nlocal = atom->nfirst;
 
   int *ilist = list->ilist;
   int *numneigh = list->numneigh;
@@ -529,7 +540,6 @@
   int npnt_middle = 0;
 
   for (i = 0; i < nlocal; i++) {
-    if (include_group && !(mask[i] & include_groupbit)) continue;
 
     if (pgsize - npnt < oneatom) {
       npnt = 0;
@@ -684,8 +694,9 @@
   int *mask = atom->mask;
   int *molecule = atom->molecule;
   int nlocal = atom->nlocal;
-  int nall = atom->nlocal + atom->nghost;
+  int nall = nlocal + atom->nghost;
   int molecular = atom->molecular;
+  if (include_group) nlocal = atom->nfirst;
 
   int *ilist = list->ilist;
   int *numneigh = list->numneigh;
@@ -718,7 +729,6 @@
   int npnt_middle = 0;
 
   for (i = 0; i < nlocal; i++) {
-    if (include_group && !(mask[i] & include_groupbit)) continue;
 
     if (pgsize - npnt < oneatom) {
       npnt = 0;
diff -Naur lammps-14Feb08/src/neighbor.cpp lammps-15Feb08/src/neighbor.cpp
--- lammps-14Feb08/src/neighbor.cpp	2008-02-14 16:05:04.000000000 -0700
+++ lammps-15Feb08/src/neighbor.cpp	2008-02-15 12:06:53.000000000 -0700
@@ -340,8 +340,6 @@
 
   n = atom->ntypes;
 
-  include_groupbit = group->bitmask[include_group];
-
   if (nex_type == 0 && nex_group == 0 && nex_mol == 0) exclude = 0;
   else exclude = 1;
 
@@ -925,27 +923,16 @@
   double delx,dely,delz,rsq;
 
   double **x = atom->x;
-  int *mask = atom->mask;
   int nlocal = atom->nlocal;
-  int flag = 0;
+  if (include_group) nlocal = atom->nfirst;
 
-  if (include_group) {
-    for (int i = 0; i < nlocal; i++)
-      if (mask[i] & include_groupbit) {
-	delx = x[i][0] - xhold[i][0];
-	dely = x[i][1] - xhold[i][1];
-	delz = x[i][2] - xhold[i][2];
-	rsq = delx*delx + dely*dely + delz*delz;
-	if (rsq > triggersq) flag = 1;
-      }
-  } else {
-    for (int i = 0; i < nlocal; i++) {
-      delx = x[i][0] - xhold[i][0];
-      dely = x[i][1] - xhold[i][1];
-      delz = x[i][2] - xhold[i][2];
-      rsq = delx*delx + dely*dely + delz*delz;
-      if (rsq > triggersq) flag = 1;
-    }
+  int flag = 0;
+  for (int i = 0; i < nlocal; i++) {
+    delx = x[i][0] - xhold[i][0];
+    dely = x[i][1] - xhold[i][1];
+    delz = x[i][2] - xhold[i][2];
+    rsq = delx*delx + dely*dely + delz*delz;
+    if (rsq > triggersq) flag = 1;
   }
 
   int flagall;
@@ -1308,8 +1295,11 @@
     } else if (strcmp(arg[iarg],"include") == 0) {
       if (iarg+2 > narg) error->all("Illegal neigh_modify command");
       include_group = group->find(arg[iarg+1]);
-      if (include_group == -1)
+      if (include_group < 0)
 	error->all("Invalid group ID in neigh_modify command");
+      if (include_group && (atom->firstgroupname == NULL ||
+			    strcmp(arg[iarg+1],atom->firstgroupname) != 0))
+	error->all("Neigh_modify include group != atom_modify first group");
       iarg += 2;
     } else if (strcmp(arg[iarg],"exclude") == 0) {
       if (iarg+2 > narg) error->all("Illegal neigh_modify command");
@@ -1417,7 +1407,7 @@
 
 void Neighbor::bin_atoms()
 {
-  int i,ibin,nall;
+  int i,ibin;
 
   for (i = 0; i < mbins; i++) binhead[i] = -1;
 
@@ -1426,15 +1416,23 @@
 
   double **x = atom->x;
   int *mask = atom->mask;
-  nall = atom->nlocal + atom->nghost;
+  int nlocal = atom->nlocal;
+  int nall = nlocal + atom->nghost;
 
   if (include_group) {
-    for (i = nall-1; i >= 0; i--)
-      if (mask[i] & include_groupbit) {
+    int bitmask = group->bitmask[include_group];
+    for (i = nall-1; i >= nlocal; i--) {
+      if (mask[i] & bitmask) {
 	ibin = coord2bin(x[i]);
 	bins[i] = binhead[ibin];
 	binhead[ibin] = i;
       }
+    }
+    for (i = atom->nfirst; i >= 0; i--) {
+      ibin = coord2bin(x[i]);
+      bins[i] = binhead[ibin];
+      binhead[ibin] = i;
+    }
   } else {
     for (i = nall-1; i >= 0; i--) {
       ibin = coord2bin(x[i]);
diff -Naur lammps-14Feb08/src/neighbor.h lammps-15Feb08/src/neighbor.h
--- lammps-14Feb08/src/neighbor.h	2008-02-14 16:05:04.000000000 -0700
+++ lammps-15Feb08/src/neighbor.h	2008-02-15 12:06:53.000000000 -0700
@@ -123,8 +123,7 @@
 
   int special_flag[4];             // flags for 1-2, 1-3, 1-4 neighbors
 
-  int include_group;               // only form neighbor lists on this group
-  int include_groupbit;
+  int include_group;               // only build pairwise lists for this group
 
   int exclude;                     // 0 if no type/group exclusions, 1 if yes