func RemoveClusterAppReference(
	clusterNamespace string,
	clusterName string,
	appCatalog string,
	appID string,
) {
	key := makeKey(clusterNamespace, appCatalog, appID)
	element := clusterNamespace + "/" + clusterName
	clustersUsingAppLock.Lock()
	defer clustersUsingAppLock.Unlock()
	if value, ok := clustersUsingApp[key]; ok {
		for i, e := range value {
			if e == element {
				numElements := len(value)
				if numElements == 1 {
					delete(clustersUsingApp, key)
				} else {
					value[i] = value[numElements-1]
					clustersUsingApp[key] = value[:numElements-1]
				}
			}
		}
	}
}
RemoveClusterAppReference notes that an app type is no longer in use by
this cluster. The cluster namespace+name is removed from the list of
such references marked against the app's namespace+name. Note that we only
expect this to be called when a reference to the cluster does exist; but
if for some reason the reference does not exist this call is a NOP.
package shared
import (
	"sync"
)
var (
	clustersUsingApp     map[string][]string
	clustersUsingAppLock sync.RWMutex
)
func init() {
	clustersUsingApp = make(map[string][]string)
}
func AnyClusters() bool {
	clustersUsingAppLock.RLock()
	defer clustersUsingAppLock.RUnlock()
	return (len(clustersUsingApp) != 0)
}
func ClustersUsingApp(
	appNamespace string,
	appID string,
) []string {
	key := appNamespace + "/" + appID
	clustersUsingAppLock.RLock()
	defer clustersUsingAppLock.RUnlock()
	if value, ok := clustersUsingApp[key]; ok {
		return value
	}
	return []string{}
}
func makeKey(
	clusterNamespace string,
	appCatalog string,
	appID string,
) string {
	if appCatalog == AppCatalogLocal {
		return clusterNamespace + "/" + appID
	}
	kdNamespace, _ := GetKubeDirectorNamespace()
	return kdNamespace + "/" + appID
}
func EnsureClusterAppReference(
	clusterNamespace string,
	clusterName string,
	appCatalog string,
	appID string,
) {
	key := makeKey(clusterNamespace, appCatalog, appID)
	newElement := clusterNamespace + "/" + clusterName
	clustersUsingAppLock.Lock()
	defer clustersUsingAppLock.Unlock()
	if value, ok := clustersUsingApp[key]; ok {
		if !StringInList(newElement, value) {
			clustersUsingApp[key] = append(value, newElement)
		}
	} else {
		clustersUsingApp[key] = []string{newElement}
	}
}