diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 3d73ffc63ee4c719f751d19c9607e261acbabcc8..b145a3178f7e32740c5c9fdf98e8bbfabda04fae 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -43,3 +43,14 @@ src/USER-MISC/*_grem.*              @dstelter92
 
 # tools
 tools/msi2lmp/*       @akohlmey
+
+# cmake
+cmake/*               @junghans @rbberger
+
+# python
+python/*              @rbberger
+
+# docs
+doc/utils/*/*         @rbberger
+doc/Makefile          @rbberger
+doc/README            @rbberger
diff --git a/doc/Makefile b/doc/Makefile
index 0a5dbe1e7d64be21628f6e85e0e72a7468752d57..c8cc8bc1bd027947165d30d79df3a0a8f3c0d73b 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -9,6 +9,7 @@ TXT2RST       = $(VENV)/bin/txt2rst
 ANCHORCHECK   = $(VENV)/bin/doc_anchor_check
 
 PYTHON        = $(shell which python3)
+VIRTUALENV     = virtualenv
 HAS_PYTHON3    = NO
 HAS_VIRTUALENV = NO
 
@@ -16,7 +17,13 @@ ifeq ($(shell which python3 >/dev/null 2>&1; echo $$?), 0)
 HAS_PYTHON3 = YES
 endif
 
+ifeq ($(shell which virtualenv-3 >/dev/null 2>&1; echo $$?), 0)
+VIRTUALENV     = virtualenv-3
+HAS_VIRTUALENV = YES
+endif
+
 ifeq ($(shell which virtualenv >/dev/null 2>&1; echo $$?), 0)
+VIRTUALENV     = virtualenv
 HAS_VIRTUALENV = YES
 endif
 
@@ -158,7 +165,7 @@ $(VENV):
 	@if [ "$(HAS_PYTHON3)" == "NO" ] ; then echo "Python3 was not found! Please check README.md for further instructions" 1>&2; exit 1; fi
 	@if [ "$(HAS_VIRTUALENV)" == "NO" ] ; then echo "virtualenv was not found! Please check README.md for further instructions" 1>&2; exit 1; fi
 	@( \
-		virtualenv -p $(PYTHON) $(VENV); \
+		$(VIRTUALENV) -p $(PYTHON) $(VENV); \
 		. $(VENV)/bin/activate; \
 		pip install Sphinx; \
 		pip install sphinxcontrib-images; \
diff --git a/doc/src/Section_errors.txt b/doc/src/Section_errors.txt
index 2821f1ff5d046d9b6ef94d8dc4a1e3eb8cb70b58..95482b06dc5bc1d768a0e4c355d8aad5e5e08821 100644
--- a/doc/src/Section_errors.txt
+++ b/doc/src/Section_errors.txt
@@ -803,6 +803,13 @@ lo value must be less than the hi value for all 3 dimensions. :dd
 The box command cannot be used after a read_data, read_restart, or
 create_box command. :dd
 
+{BUG: restartinfo=1 but no restart support in pair style} :dt
+
+The pair style has a bug, where it does not support reading
+and writing information to a restart file, but does not set
+the member variable restartinfo to 0 as required in that case. :dd
+
+
 {CPU neighbor lists must be used for ellipsoid/sphere mix.} :dt
 
 When using Gay-Berne or RE-squared pair styles with both ellipsoidal and
diff --git a/doc/src/create_bonds.txt b/doc/src/create_bonds.txt
index 6af69214d3c4523318945c3bf70ac0547621dd64..6700ed29d3f3f6d9b3c7d5094b182a1bf6235a82 100644
--- a/doc/src/create_bonds.txt
+++ b/doc/src/create_bonds.txt
@@ -37,8 +37,8 @@ keyword = {special} :l
 
 create_bonds many all all 1 1.0 1.2
 create_bonds many surf solvent 3 2.0 2.4
-create_bond single/bond 1 1 2
-create_bond single/angle 5 52 98 107 special no :pre
+create_bonds single/bond 1 1 2
+create_bonds single/angle 5 52 98 107 special no :pre
 
 [Description:]
 
diff --git a/doc/src/fix_adapt.txt b/doc/src/fix_adapt.txt
index 19d1009b8a838829c0dfee1adde7526134d29053..7a34f2ff4480004c3ff249957b2b36204a087035 100644
--- a/doc/src/fix_adapt.txt
+++ b/doc/src/fix_adapt.txt
@@ -205,6 +205,14 @@ a bond coefficient over time, very similar to how the {pair} keyword
 operates. The only difference is that now a bond coefficient for a
 given bond type is adapted.
 
+A wild-card asterisk can be used in place of or in conjunction with
+the bond type argument to set the coefficients for multiple bond types.
+This takes the form "*" or "*n" or "n*" or "m*n".  If N = the number of
+atom types, then an asterisk with no numeric values means all types
+from 1 to N.  A leading asterisk means all types from 1 to n (inclusive).
+A trailing asterisk means all types from n to N (inclusive).  A middle
+asterisk means all types from m to n (inclusive).
+
 Currently {bond} does not support bond_style hybrid nor bond_style
 hybrid/overlay as bond styles. The only bonds that currently are
 working with fix_adapt are
diff --git a/doc/src/molecule.txt b/doc/src/molecule.txt
index ecec62256a82a3b2e67f9fe64a2af6f796f0c66e..cd9ecce42c8b8750e52389e6b48c08885a7cae3f 100644
--- a/doc/src/molecule.txt
+++ b/doc/src/molecule.txt
@@ -98,19 +98,20 @@ molecule (header keyword = inertia).
 NOTE: The molecule command can be used to define molecules with bonds,
 angles, dihedrals, imporopers, or special bond lists of neighbors
 within a molecular topology, so that you can later add the molecules
-to your simulation, via one or more of the commands listed above.  If
-such molecules do not already exist when LAMMPS creates the simulation
-box, via the "create_box"_create_box.html or
-"read_data"_read_data.html command, when you later add them you may
-overflow the pre-allocated data structures which store molecular
-topology information with each atom, and an error will be generated.
-Both the "create_box"_create_box.html command and the data files read
-by the "read_data"_read_data.html command have "extra" options which
+to your simulation, via one or more of the commands listed above.
+Since this topology-related information requires that suitable storage
+is reserved when LAMMPS creates the simulation box (e.g. when using
+the "create_box"_create_box.html command or the
+"read_data"_read_data.html command) suitable space has to be reserved
+so you do not overflow those pre-allocated data structures when adding
+molecules later.  Both the "create_box"_create_box.html command and
+the "read_data"_read_data.html command have "extra" options which
 insure space is allocated for storing topology info for molecules that
 are added later.
 
-The format of an individual molecule file is similar to the data file
-read by the "read_data"_read_data.html commands, and is as follows.
+The format of an individual molecule file is similar but
+(not identical) to the data file read by the "read_data"_read_data.html
+commands, and is as follows.
 
 A molecule file has a header and a body.  The header appears first.
 The first line of the header is always skipped; it typically contains
@@ -455,7 +456,11 @@ of SHAKE clusters.
 
 :line
 
-[Restrictions:] none
+[Restrictions:]
+
+This command must come after the simulation box is define by a
+"read_data"_read_data.html, "read_restart"_read_restart.html, or
+"create_box"_create_box.html command.
 
 [Related commands:]
 
diff --git a/src/USER-QUIP/pair_quip.cpp b/src/USER-QUIP/pair_quip.cpp
index 3bf12d19d2ab3217e44bea084f53523706328425..0c00a5ef59309b824e1c534d58a6fcff9df79ceb 100644
--- a/src/USER-QUIP/pair_quip.cpp
+++ b/src/USER-QUIP/pair_quip.cpp
@@ -40,6 +40,7 @@ using namespace LAMMPS_NS;
 PairQUIP::PairQUIP(LAMMPS *lmp) : Pair(lmp)
 {
    single_enable = 0;
+   restartinfo = 0;
    one_coeff = 1;
    no_virial_fdotr_compute = 1;
    manybody_flag = 1;
diff --git a/src/error.cpp b/src/error.cpp
index 2ab816c992ac910fd0a2dd789a1c08d3f9da2576..d516050385c212ae0c8eb7da4466778baf96a447 100644
--- a/src/error.cpp
+++ b/src/error.cpp
@@ -28,7 +28,7 @@ static const char *truncpath(const char *path)
    if (path) {
      int len = strlen(path);
      for (int i = len-4; i > 0; --i) {
-	if (strncmp("src/",path+i,4) == 0)
+        if (strncmp("src/",path+i,4) == 0)
           return path+i;
      }
    }
diff --git a/src/fix_adapt.cpp b/src/fix_adapt.cpp
index 754c9ea4da41230b46836b28ca69a6e990c77b05..42cd1bd1992de2c9d474b018634bd33052e8b03f 100644
--- a/src/fix_adapt.cpp
+++ b/src/fix_adapt.cpp
@@ -118,7 +118,7 @@ nadapt(0), id_fix_diam(NULL), id_fix_chg(NULL), adapt(NULL)
       adapt[nadapt].bparam = new char[n];
       adapt[nadapt].bond = NULL;
       strcpy(adapt[nadapt].bparam,arg[iarg+2]);
-      force->bounds(FLERR,arg[iarg+3],atom->ntypes,
+      force->bounds(FLERR,arg[iarg+3],atom->nbondtypes,
                     adapt[nadapt].ilo,adapt[nadapt].ihi);
       if (strstr(arg[iarg+4],"v_") == arg[iarg+4]) {
         n = strlen(&arg[iarg+4][2]) + 1;
diff --git a/src/molecule.cpp b/src/molecule.cpp
index 56e56dab2cd16ef45c9c6068161c29a4815d51ca..dfbe3e1e08e07527096f6db6d4de80557c370415 100644
--- a/src/molecule.cpp
+++ b/src/molecule.cpp
@@ -52,6 +52,9 @@ Molecule::Molecule(LAMMPS *lmp, int narg, char **arg, int &index) :
 
   if (index >= narg) error->all(FLERR,"Illegal molecule command");
 
+  if (domain->box_exist == 0)
+    error->all(FLERR,"Molecule command before simulation box is defined");
+
   int n = strlen(arg[0]) + 1;
   id = new char[n];
   strcpy(id,arg[0]);
@@ -684,7 +687,7 @@ void Molecule::types(char *line)
   }
 
   for (int i = 0; i < natoms; i++)
-    if (type[i] <= 0)
+    if (type[i] <= 0 || type[i] > atom->ntypes)
       error->all(FLERR,"Invalid atom type in molecule file");
 
   for (int i = 0; i < natoms; i++)
@@ -771,10 +774,10 @@ void Molecule::bonds(int flag, char *line)
       error->all(FLERR,"Invalid Bonds section in molecule file");
     itype += boffset;
 
-    if (atom1 <= 0 || atom1 > natoms ||
-        atom2 <= 0 || atom2 > natoms)
+    if ((atom1 <= 0) || (atom1 > natoms) ||
+        (atom2 <= 0) || (atom2 > natoms) || (atom1 == atom2))
       error->one(FLERR,"Invalid atom ID in Bonds section of molecule file");
-    if (itype <= 0)
+    if (itype <= 0 || itype > atom->nbondtypes)
       error->one(FLERR,"Invalid bond type in Bonds section of molecule file");
 
     if (flag) {
@@ -829,11 +832,12 @@ void Molecule::angles(int flag, char *line)
       error->all(FLERR,"Invalid Angles section in molecule file");
     itype += aoffset;
 
-    if (atom1 <= 0 || atom1 > natoms ||
-        atom2 <= 0 || atom2 > natoms ||
-        atom3 <= 0 || atom3 > natoms)
+    if ((atom1 <= 0) || (atom1 > natoms) ||
+        (atom2 <= 0) || (atom2 > natoms) ||
+        (atom3 <= 0) || (atom3 > natoms) ||
+        (atom1 == atom2) || (atom1 == atom3) || (atom2 == atom3))
       error->one(FLERR,"Invalid atom ID in Angles section of molecule file");
-    if (itype <= 0)
+    if (itype <= 0 || itype > atom->nangletypes)
       error->one(FLERR,"Invalid angle type in Angles section of molecule file");
 
     if (flag) {
@@ -902,13 +906,15 @@ void Molecule::dihedrals(int flag, char *line)
       error->all(FLERR,"Invalid Dihedrals section in molecule file");
     itype += doffset;
 
-    if (atom1 <= 0 || atom1 > natoms ||
-        atom2 <= 0 || atom2 > natoms ||
-        atom3 <= 0 || atom3 > natoms ||
-        atom4 <= 0 || atom4 > natoms)
+    if ((atom1 <= 0) || (atom1 > natoms) ||
+        (atom2 <= 0) || (atom2 > natoms) ||
+        (atom3 <= 0) || (atom3 > natoms) ||
+        (atom4 <= 0) || (atom4 > natoms) ||
+        (atom1 == atom2) || (atom1 == atom3) || (atom1 == atom4) ||
+        (atom2 == atom3) || (atom2 == atom4) || (atom3 == atom4))
       error->one(FLERR,
                  "Invalid atom ID in dihedrals section of molecule file");
-    if (itype <= 0)
+    if (itype <= 0 || itype > atom->ndihedraltypes)
       error->one(FLERR,
                  "Invalid dihedral type in dihedrals section of molecule file");
 
@@ -989,13 +995,15 @@ void Molecule::impropers(int flag, char *line)
       error->all(FLERR,"Invalid Impropers section in molecule file");
     itype += ioffset;
 
-    if (atom1 <= 0 || atom1 > natoms ||
-        atom2 <= 0 || atom2 > natoms ||
-        atom3 <= 0 || atom3 > natoms ||
-        atom4 <= 0 || atom4 > natoms)
+    if ((atom1 <= 0) || (atom1 > natoms) ||
+        (atom2 <= 0) || (atom2 > natoms) ||
+        (atom3 <= 0) || (atom3 > natoms) ||
+        (atom4 <= 0) || (atom4 > natoms) ||
+        (atom1 == atom2) || (atom1 == atom3) || (atom1 == atom4) ||
+        (atom2 == atom3) || (atom2 == atom4) || (atom3 == atom4))
       error->one(FLERR,
                  "Invalid atom ID in impropers section of molecule file");
-    if (itype <= 0)
+    if (itype <= 0 || itype > atom->nimpropertypes)
       error->one(FLERR,
                  "Invalid improper type in impropers section of molecule file");
 
diff --git a/src/pair.cpp b/src/pair.cpp
index 73dbb9428e37939a7a407ad70d8b9ea516a8a133..9bb1ad212f19de34473e5f115d22b3c8bebe2acb 100644
--- a/src/pair.cpp
+++ b/src/pair.cpp
@@ -695,7 +695,15 @@ void Pair::compute_dummy(int eflag, int vflag)
 /* ---------------------------------------------------------------------- */
 void Pair::read_restart(FILE *)
 {
-  error->all(FLERR,"BUG: restartinfo=1 but no restart support in pair style");
+  if (comm->me == 0)
+    error->warning(FLERR,"BUG: restartinfo=1 but no restart support in pair style");
+}
+
+/* ---------------------------------------------------------------------- */
+void Pair::write_restart(FILE *)
+{
+  if (comm->me == 0)
+    error->warning(FLERR,"BUG: restartinfo=1 but no restart support in pair style");
 }
 
 /* -------------------------------------------------------------------
diff --git a/src/pair.h b/src/pair.h
index 26488103a05e2044d537f31dcf8a4b8b2fa0073b..844bc0cdc75c12983d98da16273b70c1257044a8 100644
--- a/src/pair.h
+++ b/src/pair.h
@@ -157,7 +157,7 @@ class Pair : protected Pointers {
   virtual void free_tables();
   virtual void free_disp_tables();
 
-  virtual void write_restart(FILE *) {}
+  virtual void write_restart(FILE *);
   virtual void read_restart(FILE *);
   virtual void write_restart_settings(FILE *) {}
   virtual void read_restart_settings(FILE *) {}
@@ -303,7 +303,9 @@ No kspace style is defined.
 
 E: BUG: restartinfo=1 but no restart support in pair style
 
-UNDOCUMENTED
+The pair style has a bug, where it does not support reading
+and writing information to a restart file, but does not set
+the member variable restartinfo to 0 as required in that case.
 
 E: Cannot yet use compute tally with Kokkos