Index: sasmodels/compare.py
===================================================================
--- sasmodels/compare.py	(revision f3bd37f99d853f8f0b06b6efe0686cbbad86974b)
+++ sasmodels/compare.py	(revision 256dfe1527a1dc32e1e2b9114144fb1c47f2b256)
@@ -387,5 +387,5 @@
     from sas.models.MultiplicationModel import MultiplicationModel
 
-    def get_model(name):
+    def get_model_class(name):
         # type: (str) -> "sas.models.BaseComponent"
         #print("new",sorted(_pars.items()))
@@ -394,5 +394,12 @@
         if ModelClass is None:
             raise ValueError("could not find model %r in sas.models"%name)
-        return ModelClass()
+        return ModelClass
+
+    # WARNING: ugly hack when handling model!
+    # Sasview models with multiplicity need to be created with the target
+    # multiplicity, so we cannot create the target model ahead of time for
+    # for multiplicity models.  Instead we store the model in a list and
+    # update the first element of that list with the new multiplicity model
+    # every time we evaluate.
 
     # grab the sasview model, or create it if it is a product model
@@ -401,5 +408,5 @@
         if composition_type == 'product':
             P, S = [get_model(revert_name(p)) for p in parts]
-            model = MultiplicationModel(P, S)
+            model = [MultiplicationModel(P, S)]
         else:
             raise ValueError("sasview mixture models not supported by compare")
@@ -409,5 +416,6 @@
             raise ValueError("model %r does not exist in old sasview"
                             % model_info.id)
-        model = get_model(old_name)
+        ModelClass = get_model_class(old_name)
+        model = [ModelClass()]
 
     # build a smearer with which to call the model, if necessary
@@ -421,12 +429,15 @@
             smearer.accuracy = data.accuracy
             smearer.set_index(index)
-            theory = lambda: smearer.get_value()
+            def _call_smearer():
+                smearer.model = model[0]
+                return smearer.get_value()
+            theory = lambda: _call_smearer()
         else:
-            theory = lambda: model.evalDistribution([data.qx_data[index],
-                                                     data.qy_data[index]])
+            theory = lambda: model[0].evalDistribution([data.qx_data[index],
+                                                        data.qy_data[index]])
     elif smearer is not None:
-        theory = lambda: smearer(model.evalDistribution(data.x))
+        theory = lambda: smearer(model[0].evalDistribution(data.x))
     else:
-        theory = lambda: model.evalDistribution(data.x)
+        theory = lambda: model[0].evalDistribution(data.x)
 
     def calculator(**pars):
@@ -435,12 +446,15 @@
         Sasview calculator for model.
         """
+        # For multiplicity models, recreate the model the first time the
+        if model_info.control:
+            model[0] = ModelClass(int(pars[model_info.control]))
         # paying for parameter conversion each time to keep life simple, if not fast
-        pars = revert_pars(model_info, pars)
-        for k, v in pars.items():
+        oldpars = revert_pars(model_info, pars)
+        for k, v in oldpars.items():
             name_attr = k.split('.')  # polydispersity components
             if len(name_attr) == 2:
-                model.dispersion[name_attr[0]][name_attr[1]] = v
+                model[0].dispersion[name_attr[0]][name_attr[1]] = v
             else:
-                model.setParam(k, v)
+                model[0].setParam(k, v)
         return theory()
 
@@ -742,5 +756,5 @@
         for ext, val in parts:
             if p.length > 1:
-                dict(("%s%d%s"%(p.id,k,ext), val) for k in range(p.length))
+                dict(("%s%d%s"%(p.id,k,ext), val) for k in range(1, p.length+1))
             else:
                 pars[p.id+ext] = val
Index: sasmodels/convert.json
===================================================================
--- sasmodels/convert.json	(revision 6e7ff6d026d856e1eb236a05975a2600ba9ba2c9)
+++ sasmodels/convert.json	(revision 256dfe1527a1dc32e1e2b9114144fb1c47f2b256)
@@ -79,11 +79,11 @@
   ], 
   "core_multi_shell": [
-    "CoreMultiShellModel", 
-    {
-      "thick_shell": "thick_shell", 
-      "radius": "rad_core0", 
-      "sld": "sld_core0", 
-      "sld_shell": "sld_in_shell", 
-      "sld_solvent": "sld_solv", 
+    "CoreMultiShellModel",
+    {
+      "thickness": "thick_shell",
+      "sld": "sld_shell",
+      "radius": "rad_core0",
+      "sld_core": "sld_core0",
+      "sld_solvent": "sld_solv",
       "n": "n_shells"
     }
@@ -475,14 +475,14 @@
   ], 
   "onion": [
-    "OnionExpShellModel", 
+    "OnionModel",
     {
       "A": "A_shell", 
-      "core_sld": "sld_core0", 
+      "sld_core": "sld_core0",
       "core_radius": "rad_core0", 
-      "out_sld": "sld_out_shell", 
-      "n": "n_shells", 
-      "solvent_sld": "sld_solv", 
+      "n": "n_shells",
+      "sld_solvent": "sld_solv",
       "thickness": "thick_shell", 
-      "in_sld": "sld_in_shell"
+      "sld_in": "sld_in_shell",
+      "sld_out": "sld_out_shell"
     }
   ], 
Index: sasmodels/convert.py
===================================================================
--- sasmodels/convert.py	(revision 7ae2b7f85895f1eddd6ef18f37ff501467a34961)
+++ sasmodels/convert.py	(revision 256dfe1527a1dc32e1e2b9114144fb1c47f2b256)
@@ -2,4 +2,6 @@
 Convert models to and from sasview.
 """
+from __future__ import print_function
+
 from os.path import join as joinpath, abspath, dirname
 import warnings
@@ -28,4 +30,12 @@
 ]
 
+MODELS_WITHOUT_VOLFRACTION = [
+    'fractal',
+    'vesicle',
+    'multilayer_vesicle',
+    'core_multi_shell',
+]
+
+
 # Convert new style names for polydispersity info to old style names
 PD_DOT = [
@@ -103,4 +113,7 @@
     # model name mapping
 
+def _unscale(par, scale):
+    return [pk*scale for pk in par] if isinstance(par, list) else par*scale
+
 def _unscale_sld(pars):
     """
@@ -109,6 +122,6 @@
     new model definition end with sld.
     """
-    return dict((p, (v*1e-6 if p.startswith('sld') or p.endswith('sld')
-                     else v*1e15 if 'ndensity' in p
+    return dict((p, (_unscale(v,1e-6) if p.startswith('sld') or p.endswith('sld')
+                     else _unscale(v,1e15) if 'ndensity' in p
                      else v))
                 for p, v in pars.items())
@@ -155,7 +168,30 @@
     return oldname
 
-def _get_old_pars(model_info):
+def _get_translation_table(model_info):
     _read_conversion_table()
-    oldname, oldpars = CONVERSION_TABLE.get(model_info.id, [None, {}])
+    _, translation = CONVERSION_TABLE.get(model_info.id, [None, {}])
+    translation = translation.copy()
+    for p in model_info.parameters.kernel_parameters:
+        if p.length > 1:
+            newid = p.id
+            oldid = translation.get(p.id, p.id)
+            del translation[newid]
+            for k in range(1, p.length+1):
+                translation[newid+str(k)] = oldid+str(k)
+    # Remove control parameter from the result
+    if model_info.control:
+        translation[model_info.control] = None
+    return translation
+
+def _trim_vectors(model_info, pars, oldpars):
+    _read_conversion_table()
+    _, translation = CONVERSION_TABLE.get(model_info.id, [None, {}])
+    for p in model_info.parameters.kernel_parameters:
+        if p.length_control is not None:
+            n = int(pars[p.length_control])
+            oldname = translation.get(p.id, p.id)
+            for k in range(n+1, p.length+1):
+                for _, old in PD_DOT:
+                    oldpars.pop(oldname+str(k)+old, None)
     return oldpars
 
@@ -174,6 +210,7 @@
             raise NotImplementedError("cannot convert to sasview sum")
     else:
-        oldpars = _get_old_pars(model_info)
-    oldpars = _revert_pars(_unscale_sld(pars), oldpars)
+        translation = _get_translation_table(model_info)
+    oldpars = _revert_pars(_unscale_sld(pars), translation)
+    oldpars = _trim_vectors(model_info, pars, oldpars)
 
 
@@ -194,4 +231,6 @@
     namelist = name.split('*') if '*' in name else [name]
     for name in namelist:
+        if name in MODELS_WITHOUT_VOLFRACTION:
+            del oldpars['volfraction']
         if name == 'stacked_disks':
             _remove_pd(oldpars, 'n_stacking', name)
@@ -211,10 +250,4 @@
         elif name in ['mono_gauss_coil','poly_gauss_coil']:
             del oldpars['i_zero']
-        elif name == 'fractal':
-            del oldpars['volfraction']
-        elif name == 'vesicle':
-            del oldpars['volfraction']
-        elif name == 'multilayer_vesicle':
-            del oldpars['volfraction']
 
     return oldpars
@@ -240,4 +273,6 @@
     namelist = name.split('*') if '*' in name else [name]
     for name in namelist:
+        if name in MODELS_WITHOUT_VOLFRACTION:
+            pars['volfraction'] = 1
         if name == 'pearl_necklace':
             pars['string_thickness_pd_n'] = 0
@@ -252,9 +287,3 @@
         elif name == 'poly_gauss_coil':
             pars['i_zero'] = 1
-        elif name == 'fractal':
-            pars['volfraction'] = 1
-        elif name == 'vesicle':
-            pars['volfraction'] = 1
-        elif name == 'multilayer_vesicle':
-            pars['volfraction'] = 1
-            
+
Index: sasmodels/modelinfo.py
===================================================================
--- sasmodels/modelinfo.py	(revision 98ba1fc38e250863fdc3ca07aff2367b3a8cce0a)
+++ sasmodels/modelinfo.py	(revision 256dfe1527a1dc32e1e2b9114144fb1c47f2b256)
@@ -186,4 +186,7 @@
         vectors = dict((name,value) for name,value in pars.items()
                        if name in lookup and lookup[name].length > 1)
+        #print("lookup", lookup)
+        #print("scalars", scalars)
+        #print("vectors", vectors)
         if vectors:
             for name, value in vectors.items():
@@ -194,11 +197,12 @@
                         key = name+str(k)
                         if key not in scalars:
-                            scalars[key] = vectors
+                            scalars[key] = value
                 else:
                     # supoprt for the form
                     #    dict(thickness=[20,10,3])
                     for (k,v) in enumerate(value):
-                        scalars[name+str(k)] = v
+                        scalars[name+str(k+1)] = v
         result.update(scalars)
+        #print("expanded", result)
 
     return result
@@ -402,6 +406,4 @@
     parameters don't use vector notation, and instead use p1, p2, ...
 
-    * *control_parameters* is the
-
     """
     # scale and background are implicit parameters
@@ -455,7 +457,6 @@
                          if p.polydisperse and p.type != 'magnetic')
 
-
     def _set_vector_lengths(self):
-        # type: () -> None
+        # type: () -> List[str]
         """
         Walk the list of kernel parameters, setting the length field of the
@@ -466,7 +467,10 @@
         initially created.
 
+        Returns the list of control parameter names.
+
         Note: This modifies the underlying parameter object.
         """
         # Sort out the length of the vector parameters such as thickness[n]
+
         for p in self.kernel_parameters:
             if p.length_control:
@@ -478,4 +482,5 @@
                                      % (p.length_control, p.name))
                 ref.is_control = True
+                ref.polydisperse = False
                 low, high = ref.limits
                 if int(low) != low or int(high) != high or low < 0 or high > 20:
@@ -689,5 +694,9 @@
     info.profile = getattr(kernel_module, 'profile', None) # type: ignore
     info.sesans = getattr(kernel_module, 'sesans', None) # type: ignore
-    info.control = getattr(kernel_module, 'control', None)
+
+    # multiplicity info
+    control_pars = [p.id for p in parameters.kernel_parameters if p.is_control]
+    default_control = control_pars[0] if control_pars else None
+    info.control = getattr(kernel_module, 'control', default_control)
     info.hidden = getattr(kernel_module, 'hidden', None) # type: ignore
 
