// <rdar://8202424>
IOReturn IOAudioSelectorControl::addAvailableSelection(SInt32 selectionValue, OSString *selectionDescription, const char* tagName, OSObject* tag)
{
	OSArray *newSelections;
	OSArray *oldAvailableSelections;
    IOReturn result = kIOReturnSuccess;
    
	oldAvailableSelections = availableSelections;
	newSelections = OSArray::withArray(availableSelections);
	if (!newSelections)
		return kIOReturnNoMemory;

    if (selectionDescription == NULL) {
        result = kIOReturnBadArgument;
    } else {
        if (valueExists(selectionValue)) {
            result = kIOReturnError;
        } else {
            OSDictionary *newSelection;
            
            newSelection = OSDictionary::withCapacity(2);
            
            if (newSelection) {
                OSNumber *number;
				
                number = OSNumber::withNumber(selectionValue, sizeof(SInt32)*8);
                
                if (number) {
                    newSelection->setObject(kIOAudioSelectorControlSelectionValueKey, number);
                    newSelection->setObject(kIOAudioSelectorControlSelectionDescriptionKey, selectionDescription);
                    newSelections->setObject(newSelection);
					
                    number->release();
                } else {
                    result = kIOReturnError;
                }
				
				if ( tagName && tag ) {
					newSelection->setObject(tagName, tag);
				}
				
				availableSelections = newSelections;
				setProperty(kIOAudioSelectorControlAvailableSelectionsKey, availableSelections);
				oldAvailableSelections->release();
                
                newSelection->release();
            } else {
                result = kIOReturnError;
            }
        }
    }
    
	if (kIOReturnSuccess == result) {
		sendChangeNotification(kIOAudioControlRangeChangeNotification);
	}
	
    return result;
}
IOReturn IOAudioSelectorControl::replaceAvailableSelection(SInt32 selectionValue, OSString *selectionDescription)
{
    OSCollectionIterator *iterator;
	OSArray *newSelections;
	OSArray *oldAvailableSelections;
    IOReturn result = kIOReturnSuccess;
    
    assert(availableSelections);

	oldAvailableSelections = availableSelections;
	newSelections = OSArray::withArray(availableSelections);
	if (!newSelections)
		return kIOReturnNoMemory;

    iterator = OSCollectionIterator::withCollection(newSelections);
    if (iterator) {
        OSDictionary *	selection;
		UInt32			index;

		index = 0;
        while ( (selection = (OSDictionary *)iterator->getNextObject() )) {
            OSNumber *	sValue;

            sValue = (OSNumber *)selection->getObject(kIOAudioSelectorControlSelectionValueKey);

            if (sValue && ((SInt32)sValue->unsigned32BitValue() == selectionValue)) {
				// Replace the selected dictionary in the array
				newSelections->replaceObject(index, selectionDescription);
				result = kIOReturnSuccess;
                break;
            }
			index++;
        }
		availableSelections = newSelections;
        setProperty(kIOAudioSelectorControlAvailableSelectionsKey, availableSelections);
		oldAvailableSelections->release();

        iterator->release();
    }

	if (kIOReturnSuccess == result) {
		sendChangeNotification(kIOAudioControlRangeChangeNotification);
	}

    return result;
}
void IOAudioControlUserClient::sendValueChangeNotification()
{
	return sendChangeNotification(kIOAudioControlValueChangeNotification);
}
void IOAudioLevelControl::setMaxDB(IOFixed newMaxDB)
{
    setProperty(kIOAudioLevelControlMaxDBKey, newMaxDB, sizeof(IOFixed)*8);
	sendChangeNotification(kIOAudioControlRangeChangeNotification);
}
void IOAudioLevelControl::setMaxValue(SInt32 newMaxValue)
{
    maxValue = newMaxValue;
    setProperty(kIOAudioLevelControlMaxValueKey, newMaxValue, sizeof(SInt32)*8);
	sendChangeNotification(kIOAudioControlRangeChangeNotification);
}