diff --git a/src/USER-DPD/nbin_ssa.cpp b/src/USER-DPD/nbin_ssa.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d55acb6040cf2fc3e9e0d4b1605449c2e510d326
--- /dev/null
+++ b/src/USER-DPD/nbin_ssa.cpp
@@ -0,0 +1,129 @@
+/* ----------------------------------------------------------------------
+   LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+   http://lammps.sandia.gov, Sandia National Laboratories
+   Steve Plimpton, sjplimp@sandia.gov
+
+   Copyright (2003) Sandia Corporation.  Under the terms of Contract
+   DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+   certain rights in this software.  This software is distributed under
+   the GNU General Public License.
+
+   See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+   Contributing authors:
+   James Larentzos (ARL) and Timothy I. Mattox (Engility Corporation)
+------------------------------------------------------------------------- */
+
+#include "nbin_ssa.h"
+#include "atom.h"
+#include "group.h"
+#include "memory.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+NBinSSA::NBinSSA(LAMMPS *lmp) : NBinStandard(lmp)
+{
+  maxbin_ssa = 0;
+  bins_ssa = NULL;
+  maxhead_ssa = 0;
+  binhead_ssa = NULL;
+  gbinhead_ssa = NULL;
+}
+
+NBinSSA::~NBinSSA()
+{
+  memory->destroy(bins_ssa);
+  memory->destroy(binhead_ssa);
+  memory->destroy(gbinhead_ssa);
+}
+
+/* ----------------------------------------------------------------------
+   bin owned and ghost atoms for the Shardlow Splitting Algorithm (SSA)
+   local atoms are in distinct bins (binhead_ssa) from the ghosts
+   ghost atoms are in distinct bins (gbinhead_ssa) from the locals
+     ghosts which are not in an Active Interaction Region (AIR) are skipped
+------------------------------------------------------------------------- */
+
+void NBinSSA::bin_atoms()
+{
+  int i,ibin;
+  int nlocal = atom->nlocal;
+  int nall = nlocal + atom->nghost;
+  if (includegroup) nlocal = atom->nfirst;
+  double **x = atom->x;
+  int *mask = atom->mask;
+  int *ssaAIR = atom->ssaAIR;
+
+  for (i = 0; i < mbins; i++) {
+    gbinhead_ssa[i] = -1;
+    binhead_ssa[i] = -1;
+  }
+
+  // bin in reverse order so linked list will be in forward order
+
+  if (includegroup) {
+    int bitmask = group->bitmask[includegroup];
+    int nowned = atom->nlocal; // NOTE: nlocal was set to atom->nfirst above
+    for (i = nall-1; i >= nowned; i--) {
+      if (ssaAIR[i] < 2) continue; // skip ghost atoms not in AIR
+      if (mask[i] & bitmask) {
+        ibin = coord2bin(x[i]);
+        bins_ssa[i] = gbinhead_ssa[ibin];
+        gbinhead_ssa[ibin] = i;
+      }
+    }
+  } else {
+    for (i = nall-1; i >= nlocal; i--) {
+      if (ssaAIR[i] < 2) continue; // skip ghost atoms not in AIR
+      ibin = coord2bin(x[i]);
+      bins_ssa[i] = gbinhead_ssa[ibin];
+      gbinhead_ssa[ibin] = i;
+    }
+  }
+  for (i = nlocal-1; i >= 0; i--) {
+    ibin = coord2bin(x[i]);
+    bins_ssa[i] = binhead_ssa[ibin];
+    binhead_ssa[ibin] = i;
+  }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void NBinSSA::bin_atoms_setup(int nall)
+{
+  NBinStandard::bin_atoms_setup(nall); // Setup the parent class's data too
+
+  if (mbins > maxhead_ssa) {
+    maxhead_ssa = mbins;
+    memory->destroy(gbinhead_ssa);
+    memory->destroy(binhead_ssa);
+    memory->create(binhead_ssa,maxhead_ssa,"binhead_ssa");
+    memory->create(gbinhead_ssa,maxhead_ssa,"gbinhead_ssa");
+  }
+
+  if (nall > maxbin_ssa) {
+    maxbin_ssa = nall;
+    memory->destroy(bins_ssa);
+    memory->create(bins_ssa,maxbin_ssa,"bins_ssa");
+  }
+}
+
+/* ---------------------------------------------------------------------- */
+
+bigint NBinSSA::memory_usage()
+{
+  bigint bytes = NBinStandard::memory_usage(); // Count the parent's usage too
+
+  if (maxbin_ssa) bytes += memory->usage(bins_ssa,maxbin_ssa);
+  if (maxhead_ssa) {
+    bytes += memory->usage(binhead_ssa,maxhead_ssa);
+    bytes += memory->usage(gbinhead_ssa,maxhead_ssa);
+  }
+  return bytes;
+}
+
diff --git a/src/USER-DPD/nbin_ssa.h b/src/USER-DPD/nbin_ssa.h
new file mode 100644
index 0000000000000000000000000000000000000000..f0699b3a7ae2298204cacb769b9d9bb6d53e39cf
--- /dev/null
+++ b/src/USER-DPD/nbin_ssa.h
@@ -0,0 +1,54 @@
+/* -*- c++ -*- ----------------------------------------------------------
+   LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+   http://lammps.sandia.gov, Sandia National Laboratories
+   Steve Plimpton, sjplimp@sandia.gov
+
+   Copyright (2003) Sandia Corporation.  Under the terms of Contract
+   DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+   certain rights in this software.  This software is distributed under
+   the GNU General Public License.
+
+   See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifdef NBIN_CLASS
+
+NBinStyle(ssa,
+          NBinSSA,
+          NB_SSA)
+
+#else
+
+#ifndef LMP_NBIN_SSA_H
+#define LMP_NBIN_SSA_H
+
+#include "nbin_standard.h"
+
+namespace LAMMPS_NS {
+
+class NBinSSA : public NBinStandard {
+ public:
+
+  int *bins_ssa;             // index of next atom in each bin
+  int maxbin_ssa;            // size of bins_ssa array
+  int *binhead_ssa;          // index of 1st local atom in each bin
+  int *gbinhead_ssa;         // index of 1st ghost atom in each bin
+  int maxhead_ssa;           // size of binhead_ssa and gbinhead_ssa arrays
+
+  NBinSSA(class LAMMPS *);
+  ~NBinSSA();
+
+  void bin_atoms_setup(int);
+  void bin_atoms();
+
+  bigint memory_usage();
+};
+
+}
+
+#endif
+#endif
+
+/* ERROR/WARNING messages:
+
+*/
diff --git a/src/USER-DPD/npair_half_bin_newton_ssa.cpp b/src/USER-DPD/npair_half_bin_newton_ssa.cpp
index b529121a0ac301971da48095b7c751dbcac79e0b..e41b9d4276180b4f9e58e60723d00b64c417ab57 100644
--- a/src/USER-DPD/npair_half_bin_newton_ssa.cpp
+++ b/src/USER-DPD/npair_half_bin_newton_ssa.cpp
@@ -18,6 +18,7 @@
 
 #include "npair_half_bin_newton_ssa.h"
 #include "neighbor.h"
+#include "nbin_ssa.h"
 #include "neigh_list.h"
 #include "atom.h"
 #include "atom_vec.h"
@@ -78,71 +79,13 @@ void NPairHalfBinNewtonSSA::build(NeighList *list)
   int **firstneigh = list->firstneigh;
   MyPage<int> *ipage = list->ipage;
 
-  int inum = 0;
-
-  // bin owned and ghost atoms for use by Shardlow Splitting Algorithm
-  // exclude ghost atoms that are not in the Active Interaction Regions (AIR)
-
-  // NOTE to Tim: this binatomflag no longer exists
-  //   the logic up higher assures that binning has been done
-  //     before this build() method is called
-  //   maybe this code below needs to be in a new NBinShardlow class?
-  // this class also inherits NPair::nb from its parent
-  //   which points to the NBin class that did the binning
-  //   there are last_step variables stored there which indicate
-  //   the last time binning was done
-  // the basic question is what data is created/stored by SSA binning
-  //   and in what class should it live?
-  //   if it is created by the binning operation, then I think
-  //     it should be in a new NBinShardlow class
-
-  if (true /* binatomflag */) { // only false in Neighbor::build_one
-
-    if (mbins > list->maxhead_ssa) {
-      list->maxhead_ssa = mbins;
-      memory->destroy(list->gbinhead_ssa);
-      memory->destroy(list->binhead_ssa);
-      memory->create(list->binhead_ssa,list->maxhead_ssa,"binhead_ssa");
-      memory->create(list->gbinhead_ssa,list->maxhead_ssa,"gbinhead_ssa");
-    }
-    for (i = 0; i < mbins; i++) {
-      list->gbinhead_ssa[i] = -1;
-      list->binhead_ssa[i] = -1;
-    }
-
-    if (nall > list->maxbin_ssa) {
-      list->maxbin_ssa = nall;
-      memory->destroy(list->bins_ssa);
-      memory->create(list->bins_ssa,list->maxbin_ssa,"bins_ssa");
-    }
+  NBinSSA *nb_ssa = dynamic_cast<NBinSSA*>(nb);
+  if (!nb_ssa) error->one(FLERR, "NBin wasn't a NBinSSA object");
+  int *bins_ssa = nb_ssa->bins_ssa;
+  int *binhead_ssa = nb_ssa->binhead_ssa;
+  int *gbinhead_ssa = nb_ssa->gbinhead_ssa;
 
-    // bin in reverse order so linked list will be in forward order
-
-    if (includegroup) {
-      int bitmask = group->bitmask[includegroup];
-      int nowned = atom->nlocal; // NOTE: nlocal was set to atom->nfirst above
-      for (i = nall-1; i >= nowned; i--) {
-        if (ssaAIR[i] < 2) continue; // skip ghost atoms not in AIR
-        if (mask[i] & bitmask) {
-          ibin = coord2bin(x[i]);
-          list->bins_ssa[i] = list->gbinhead_ssa[ibin];
-          list->gbinhead_ssa[ibin] = i;
-        }
-      }
-    } else {
-      for (i = nall-1; i >= nlocal; i--) {
-        if (ssaAIR[i] < 2) continue; // skip ghost atoms not in AIR
-        ibin = coord2bin(x[i]);
-        list->bins_ssa[i] = list->gbinhead_ssa[ibin];
-        list->gbinhead_ssa[ibin] = i;
-      }
-    }
-    for (i = nlocal-1; i >= 0; i--) {
-      ibin = coord2bin(x[i]);
-      list->bins_ssa[i] = list->binhead_ssa[ibin];
-      list->binhead_ssa[ibin] = i;
-    }
-  }  // else reuse previous binning. See Neighbor::build_one comment
+  int inum = 0;
 
   ipage->reset();
 
@@ -166,7 +109,7 @@ void NPairHalfBinNewtonSSA::build(NeighList *list)
     // loop over rest of local atoms in i's bin
     // just store them, since j is beyond i in linked list
 
-    for (j = list->bins_ssa[i]; j >= 0; j = list->bins_ssa[j]) {
+    for (j = bins_ssa[i]; j >= 0; j = bins_ssa[j]) {
 
       jtype = type[j];
       if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
@@ -198,8 +141,8 @@ void NPairHalfBinNewtonSSA::build(NeighList *list)
     // loop over all local atoms in other bins in "half" stencil
 
     for (k = 0; k < nstencil; k++) {
-      for (j = list->binhead_ssa[ibin+stencil[k]]; j >= 0; 
-           j = list->bins_ssa[j]) {
+      for (j = binhead_ssa[ibin+stencil[k]]; j >= 0; 
+           j = bins_ssa[j]) {
 
         jtype = type[j];
         if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
@@ -234,8 +177,8 @@ void NPairHalfBinNewtonSSA::build(NeighList *list)
     // Note2: only non-pure locals can have ghosts as neighbors
 
     if (ssaAIR[i] == 1) for (k = 0; k < nstencil_ssa; k++) {
-      for (j = list->gbinhead_ssa[ibin+stencil[k]]; j >= 0; 
-           j = list->bins_ssa[j]) {
+      for (j = gbinhead_ssa[ibin+stencil[k]]; j >= 0; 
+           j = bins_ssa[j]) {
 
         jtype = type[j];
         if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
diff --git a/src/neigh_list.cpp b/src/neigh_list.cpp
index 2a29c34565d1bb16c121a58b36dc3a5145622518..dfab9b023ac6c3b1606886fd30bd2cb2e8bf78f6 100644
--- a/src/neigh_list.cpp
+++ b/src/neigh_list.cpp
@@ -70,11 +70,6 @@ NeighList::NeighList(LAMMPS *lmp) : Pointers(lmp)
   // USER-DPD package
 
   ndxAIR_ssa = NULL;
-  maxbin_ssa = 0;
-  bins_ssa = NULL;
-  maxhead_ssa = 0;
-  binhead_ssa = NULL;
-  gbinhead_ssa = NULL;
 }
 
 /* ---------------------------------------------------------------------- */
@@ -96,9 +91,6 @@ NeighList::~NeighList()
 
   if (ssa) {
     memory->sfree(ndxAIR_ssa);
-    memory->destroy(bins_ssa);
-    memory->destroy(binhead_ssa);
-    memory->destroy(gbinhead_ssa);
   }
 }
 
@@ -308,11 +300,6 @@ bigint NeighList::memory_usage()
   }
 
   if (ndxAIR_ssa) bytes += sizeof(uint16_t) * 8 * maxatom;
-  if (maxbin_ssa) bytes += memory->usage(bins_ssa,maxbin_ssa);
-  if (maxhead_ssa) {
-    bytes += memory->usage(binhead_ssa,maxhead_ssa);
-    bytes += memory->usage(gbinhead_ssa,maxhead_ssa);
-  }
 
   return bytes;
 }
diff --git a/src/neigh_list.h b/src/neigh_list.h
index 232892f8b407ec0d68b5cda22f2c9282558240b3..d3bde212c25c1294686eb0a48ed1fdfc4c071a7a 100644
--- a/src/neigh_list.h
+++ b/src/neigh_list.h
@@ -72,11 +72,6 @@ class NeighList : protected Pointers {
   // USER-DPD package and Shardlow Splitting Algorithm (SSA) support
 
   uint16_t (*ndxAIR_ssa)[8]; // for each atom, last neighbor index of each AIR
-  int *bins_ssa;             // index of next atom in each bin
-  int maxbin_ssa;            // size of bins_ssa array
-  int *binhead_ssa;          // index of 1st local atom in each bin
-  int *gbinhead_ssa;         // index of 1st ghost atom in each bin
-  int maxhead_ssa;           // size of binhead_ssa and gbinhead_ssa arrays
 
   // methods