UpdateClone(bool allClones, string cloneName, GitInstallerCredentials credentials)
        {
            // TODO: ask for closing running Revits

            // prepare a list of clones to be updated
            var targetClones = new List <PyRevitClone>();
            // separate the clone that this process might be running from
            // this is used to update this clone from outside since the dlls will be locked
            PyRevitClone myClone = null;

            // all clones
            if (allClones)
            {
                foreach (var clone in PyRevitClones.GetRegisteredClones())
                {
                    if (PyRevitCLIAppCmds.IsRunningInsideClone(clone))
                    {
                        myClone = clone;
                    }
                    else
                    {
                        targetClones.Add(clone);
                    }
                }
            }
            // or single clone
            else
            {
                if (cloneName != null)
                {
                    var clone = PyRevitClones.GetRegisteredClone(cloneName);
                    if (PyRevitCLIAppCmds.IsRunningInsideClone(clone))
                    {
                        myClone = clone;
                    }
                    else
                    {
                        targetClones.Add(clone);
                    }
                }
            }

            // update clones that do not include this process
            foreach (var clone in targetClones)
            {
                logger.Debug("Updating clone \"{0}\"", clone.Name);
                PyRevitClones.Update(clone, credentials);
            }

            // now update myClone if any, as last step
            if (myClone != null)
            {
                throw new PyRevitException("Can not update clone that contains this command line utility. "
                                           + "Use installer to update.");
            }
        }