text:
#include "../../idlib/precompiled.h"
#include "../../sound/snd_local.h"

#include <Carbon/Carbon.h>
#include <CoreAudio/CoreAudio.h>

idCVar s_device( "s_device", "-1", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_INTEGER, "Sound device to use. -1 for default device" );

class idAudioHardwareOSX : public idAudioHardware {
public:
	idAudioHardwareOSX();
    ~idAudioHardwareOSX();

    bool	Initialize( );

	// OSX driver doesn't support memory map API
	bool	Lock( void **pDSLockedBuffer, ulong *dwDSLockedBufferSize ) { return false; }
	bool	Unlock( void *pDSLockedBuffer, dword dwDSLockedBufferSize ) { return false; }
	bool	GetCurrentPosition( ulong *pdwCurrentWriteCursor ) { return false; }
	int		GetMixBufferSize( void )  { return 0; }

	int		GetNumberOfSpeakers( void );

	// OSX driver doesn't support write API
	bool	Flush( void ) { return false; }
	void	Write( bool ) { }
	short*	GetMixBuffer( void ) { return NULL; }

private:
	AudioDeviceID		selectedDevice;
	bool				activeIOProc;

	void				Reset( void );
	void				InitFailed( void );
	const char*			ExtractStatus( OSStatus status );
	void				GetAvailableNominalSampleRates( void );

	// AudioDevicePropertyListenerProc
	static OSStatus		DeviceListener(	AudioDeviceID			inDevice,
	   									UInt32					inChannel,
										Boolean					isInput,
										AudioDevicePropertyID	inPropertyID,
										void*					inClientData );

	// AudioDeviceIOProc
	static OSStatus		DeviceIOProc( AudioDeviceID				inDevice,
									  const AudioTimeStamp*		inNow,
									  const AudioBufferList*	inInputData,
									  const AudioTimeStamp*		inInputTime,
									  AudioBufferList*			outOutputData,
									  const AudioTimeStamp*		inOutputTime,
									  void*						inClientData );
};

/*
==========
iAudioHardware::Alloc
==========
*/
idAudioHardware *idAudioHardware::Alloc() { return new idAudioHardwareOSX; }

/*
==========
idAudioHardware::~idAudioHardware
==========
*/
idAudioHardware::~idAudioHardware() { }

/*
==========
idAudioHardwareOSX::idAudioHardwareOSX
==========
*/
idAudioHardwareOSX::idAudioHardwareOSX() {
	selectedDevice = kAudioDeviceUnknown;
	activeIOProc = false;
}

/*
==========
idAudioHardwareOSX::~idAudioHardwareOSX
==========
*/
idAudioHardwareOSX::~idAudioHardwareOSX() {
	Reset();
}

/*
==========
idAudioHardwareOSX::Reset
==========
*/
void idAudioHardwareOSX::Reset() {
	OSStatus status;

	if ( activeIOProc ) {
		status = AudioDeviceStop( selectedDevice, DeviceIOProc );
		if ( status != kAudioHardwareNoError ) {
			common->Warning( "idAudioHardwareOSX::Reset: AudioDeviceStop failed. status: %s", ExtractStatus( status ) );
		}
		status = AudioDeviceRemoveIOProc( selectedDevice, DeviceIOProc );
		if ( status != kAudioHardwareNoError ) {
			common->Warning( "idAudioHardwareOSX::Reset: AudioDeviceRemoveIOProc failed. status %s\n", ExtractStatus( status ) );
		}
		activeIOProc = false;
	}
	selectedDevice = kAudioDeviceUnknown;
	AudioHardwareUnload();
}

/*
=================
idAudioHardwareOSX::InitFailed
=================
*/
void idAudioHardwareOSX::InitFailed() {
	Reset();
	cvarSystem->SetCVarBool( "s_noSound", true );
	common->Warning( "sound subsystem disabled" );
	common->Printf( "------------------------------------------------\n" );
}

/*
==========
idAudioHardwareOSX::DeviceListener
==========
*/
OSStatus idAudioHardwareOSX::DeviceListener(	AudioDeviceID			inDevice,
												UInt32					inChannel,
												Boolean					isInput,
												AudioDevicePropertyID	inPropertyID,
												void*					inClientData) {
	common->Printf( "DeviceListener\n" );
	return kAudioHardwareNoError;
}

/*
==========
idAudioHardwareOSX::DeviceIOProc
==========
*/
OSStatus idAudioHardwareOSX::DeviceIOProc( AudioDeviceID			inDevice,
										   const AudioTimeStamp*	inNow,
										   const AudioBufferList*	inInputData,
										   const AudioTimeStamp*	inInputTime,
										   AudioBufferList*			outOutputData,
										   const AudioTimeStamp*	inOutputTime,
										   void*					inClientData ) {

	// setup similar to async thread
	Sys_EnterCriticalSection();
	soundSystem->AsyncMix( (int)inOutputTime->mSampleTime, (float*)outOutputData->mBuffers[ 0 ].mData );
	Sys_LeaveCriticalSection();

	// doom mixes sound to -32768.0f 32768.0f range, scale down to -1.0f 1.0f
	SIMDProcessor->Mul( (Float32*)outOutputData->mBuffers[ 0 ].mData, 1.0f / 32768.0f, (Float32*)outOutputData->mBuffers[ 0 ].mData, MIXBUFFER_SAMPLES * 2 );

	return kAudioHardwareNoError;
}

/*
==========
idAudioHardwareOSX::ExtractStatus
==========
*/
const char*	idAudioHardwareOSX::ExtractStatus( OSStatus status ) {
	static char buf[ sizeof( OSStatus ) + 1 ];
	strncpy( buf, (const char *)&status, sizeof( OSStatus ) );
	buf[ sizeof( OSStatus ) ] = '\0';
	return buf;
}

/*
==========
idAudioHardwareOSX::Initialize
==========
*/
bool idAudioHardwareOSX::Initialize( ) {

	UInt32			size;
	OSStatus		status;
	int				i, deviceCount;
	AudioDeviceID	*deviceList;
	char			buf[ 1024 ];

	status = AudioHardwareGetPropertyInfo( kAudioHardwarePropertyDevices, &size, NULL );
	if ( status != kAudioHardwareNoError ) {
		common->Warning( "AudioHardwareGetPropertyInfo kAudioHardwarePropertyDevices failed. status: %s", ExtractStatus( status ) );
		InitFailed();
		return false;
	}

	deviceCount = size / sizeof( AudioDeviceID );
	if ( !deviceCount ) {
		common->Printf( "No sound device found\n" );
		InitFailed();
		return false;
	}

	deviceList = (AudioDeviceID*)malloc( size );
	status = AudioHardwareGetProperty( kAudioHardwarePropertyDevices, &size, deviceList );
	if ( status != kAudioHardwareNoError ) {
		common->Warning( "AudioHardwareGetProperty kAudioHardwarePropertyDevices failed. status: %s", ExtractStatus( status ) );
		free( deviceList );
		InitFailed();
		return false;
	}

	common->Printf( "%d sound device(s)\n", deviceCount );
	for( i = 0; i < deviceCount; i++ ) {
		size = 1024;
		status = AudioDeviceGetProperty( deviceList[ i ], 0, false, kAudioDevicePropertyDeviceName, &size, buf );
		if ( status != kAudioHardwareNoError ) {
			common->Warning( "AudioDeviceGetProperty kAudioDevicePropertyDeviceName %d failed. status: %s", i, ExtractStatus( status ) );
			free( deviceList );
			InitFailed();
			return false;
		}
		common->Printf( "  %d: ID %d, %s - ", i, deviceList[ i ], buf );
		size = 1024;
		status = AudioDeviceGetProperty( deviceList[ i ], 0, false, kAudioDevicePropertyDeviceManufacturer, &size, buf );
		if ( status != kAudioHardwareNoError ) {
			common->Warning( "AudioDeviceGetProperty kAudioDevicePropertyDeviceManufacturer %d failed. status: %s", i, ExtractStatus( status ) );
			free( deviceList );
			InitFailed();
			return false;
		}
		common->Printf( "%s\n", buf );
	}

	if ( s_device.GetInteger() != -1 && s_device.GetInteger() < deviceCount ) {
		selectedDevice = deviceList[ s_device.GetInteger() ];
		common->Printf( "s_device: device ID %d\n", selectedDevice );
	} else {
		size = sizeof( selectedDevice );
		status = AudioHardwareGetProperty( kAudioHardwarePropertyDefaultOutputDevice, &size, &selectedDevice );
		if ( status != kAudioHardwareNoError ) {
			common->Warning( "AudioHardwareGetProperty kAudioHardwarePropertyDefaultOutputDevice failed. status: %s", ExtractStatus( status ) );

			free( deviceList );
			InitFailed();
			return false;
		}
		common->Printf( "select default device, ID %d\n", selectedDevice );
	}

	free( deviceList );
	deviceList = NULL;

	/*
	// setup a listener to watch for changes to properties
	status = AudioDeviceAddPropertyListener( selectedDevice, 0, false, kAudioDeviceProcessorOverload, DeviceListener, this );
	if ( status != kAudioHardwareNoError ) {
		common->Warning( "AudioDeviceAddPropertyListener kAudioDeviceProcessorOverload failed. status: %s", ExtractStatus( status ) );
		InitFailed();
		return;
	}
	*/

	Float64 sampleRate;
	size = sizeof( sampleRate );
	status = AudioDeviceGetProperty( selectedDevice, 0, false, kAudioDevicePropertyNominalSampleRate, &size, &sampleRate );
	if ( status != kAudioHardwareNoError ) {
		common->Warning( "AudioDeviceGetProperty %d kAudioDevicePropertyNominalSampleRate failed. status: %s", selectedDevice, ExtractStatus( status ) );
		InitFailed();
		return false;
	}
	common->Printf( "current nominal rate: %g\n", sampleRate );

	if ( sampleRate != PRIMARYFREQ ) {

		GetAvailableNominalSampleRates();

		sampleRate = PRIMARYFREQ;
		common->Printf( "setting rate to: %g\n", sampleRate );
		status = AudioDeviceSetProperty( selectedDevice, NULL, 0, false, kAudioDevicePropertyNominalSampleRate, size, &sampleRate );
		if ( status != kAudioHardwareNoError ) {
			common->Warning( "AudioDeviceSetProperty %d kAudioDevicePropertyNominalSampleRate %g failed. status: %s", selectedDevice, sampleRate, ExtractStatus( status ) );
			InitFailed();
			return false;
		}
	}

	UInt32 frameSize;
	size = sizeof( UInt32 );
	status = AudioDeviceGetProperty( selectedDevice, 0, false, kAudioDevicePropertyBufferFrameSize, &size, &frameSize );
	if ( status != kAudioHardwareNoError ) {
		common->Warning( "AudioDeviceGetProperty %d kAudioDevicePropertyBufferFrameSize failed.status: %s", selectedDevice, ExtractStatus( status ) );
		InitFailed();
		return false;
	}
	common->Printf( "current frame size: %d\n", frameSize );

	// get the allowed frame size range
	AudioValueRange frameSizeRange;
	size = sizeof( AudioValueRange );
	status = AudioDeviceGetProperty( selectedDevice, 0, false, kAudioDevicePropertyBufferFrameSizeRange, &size, &frameSizeRange );
	if ( status != kAudioHardwareNoError ) {
		common->Warning( "AudioDeviceGetProperty %d kAudioDevicePropertyBufferFrameSizeRange failed. status: %s", selectedDevice, ExtractStatus( status ) );
		InitFailed();
		return false;
	}
	common->Printf( "frame size allowed range: %g %g\n", frameSizeRange.mMinimum, frameSizeRange.mMaximum );

	if ( frameSizeRange.mMaximum < MIXBUFFER_SAMPLES ) {
		common->Warning( "can't obtain the required frame size of %d bits", MIXBUFFER_SAMPLES );
		InitFailed();
		return false;
	}

	if ( frameSize != (unsigned int)MIXBUFFER_SAMPLES ) {
		frameSize = MIXBUFFER_SAMPLES;
		common->Printf( "setting frame size to: %d\n", frameSize );
		size = sizeof( frameSize );
		status = AudioDeviceSetProperty( selectedDevice, NULL, 0, false, kAudioDevicePropertyBufferFrameSize, size, &frameSize );
		if ( status != kAudioHardwareNoError ) {
			common->Warning( "AudioDeviceSetProperty %d kAudioDevicePropertyBufferFrameSize failed. status: %s", selectedDevice, ExtractStatus( status ) );
			InitFailed();
			return false;
		}
	}

	if ( idSoundSystemLocal::s_numberOfSpeakers.GetInteger() != 2 ) {
		common->Warning( "only stereo sound currently supported" );
		idSoundSystemLocal::s_numberOfSpeakers.SetInteger( 2 );
	}
	UInt32 channels[ 2 ];
	size = 2 * sizeof( UInt32 );
	status = AudioDeviceGetProperty( selectedDevice, 0, false, 	kAudioDevicePropertyPreferredChannelsForStereo, &size, &channels );
	if ( status != kAudioHardwareNoError ) {
		common->Warning( "AudioDeviceGetProperty %d kAudioDevicePropertyPreferredChannelsForStereo failed. status: %s", selectedDevice, ExtractStatus( status ) );
		InitFailed();
		return false;
	}
	common->Printf( "using stereo channel IDs %d %d\n", channels[ 0 ], channels[ 1 ] );

	status = AudioDeviceAddIOProc( selectedDevice, DeviceIOProc, NULL );
	if ( status != kAudioHardwareNoError ) {
		common->Warning( "AudioDeviceAddIOProc failed. status: %s", ExtractStatus( status ) );
		InitFailed();
		return false;
	}
	activeIOProc = true;

	status = AudioDeviceStart( selectedDevice, DeviceIOProc );
	if ( status != kAudioHardwareNoError ) {
		common->Warning( "AudioDeviceStart failed. status: %s", ExtractStatus( status ) );
		InitFailed();
		return false;
	}

	/*
	// allocate the mix buffer
	// it has the space for ROOM_SLICES_IN_BUFFER DeviceIOProc loops
	mixBufferSize =  dwSpeakers * dwSampleSize * dwPrimaryBitRate * ROOM_SLICES_IN_BUFFER / 8;
	mixBuffer = malloc( mixBufferSize );
	memset( mixBuffer, 0, mixBufferSize );
	*/

	return true;
}

/*
==========
idAudioHardwareOSX::GetAvailableNominalSampleRates
==========
*/
void idAudioHardwareOSX::GetAvailableNominalSampleRates( void ) {
	UInt32				size;
	OSStatus			status;
	int			   		i, rangeCount;
	AudioValueRange		*rangeArray;

	status = AudioDeviceGetPropertyInfo( selectedDevice, 0, false, kAudioDevicePropertyAvailableNominalSampleRates, &size, NULL );
	if ( status != kAudioHardwareNoError ) {
		common->Warning( "AudioDeviceGetPropertyInfo %d kAudioDevicePropertyAvailableNominalSampleRates failed. status: %s", selectedDevice, ExtractStatus( status ) );
		return;
	}
	rangeCount = size / sizeof( AudioValueRange );
	rangeArray = (AudioValueRange *)malloc( size );

	common->Printf( "%d possible rate(s)\n", rangeCount );

	status = AudioDeviceGetProperty( selectedDevice, 0, false, kAudioDevicePropertyAvailableNominalSampleRates, &size, rangeArray );
	if ( status != kAudioHardwareNoError ) {
		common->Warning( "AudioDeviceGetProperty %d kAudioDevicePropertyAvailableNominalSampleRates failed. status: %s", selectedDevice, ExtractStatus( status ) );
		free( rangeArray );
		return;
	}

	for( i = 0; i < rangeCount; i++ ) {
		common->Printf( "  %d: min %g max %g\n", i, rangeArray[ i ].mMinimum, rangeArray[ i ].mMaximum );
	}

	free( rangeArray );
}

/*
==========
idAudioHardwareOSX::GetNumberOfSpeakers
==========
*/
int	idAudioHardwareOSX::GetNumberOfSpeakers() {
	return idSoundSystemLocal::s_numberOfSpeakers.GetInteger();
}

/*
 ===============
 Sys_LoadOpenAL
 ===============
 */
bool Sys_LoadOpenAL( void ) {
	OSErr	err;
	long gestaltOSVersion;
	err = Gestalt(gestaltSystemVersion, &gestaltOSVersion);
	if ( err || gestaltOSVersion < 0x1040 ) {
		return false;
	}
	return true;
}


text:
package msp

import (
	"bytes"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/asn1"
	"fmt"
	"time"

	"github.com/golang/protobuf/proto"
	m "github.com/hyperledger/fabric-protos-go/msp"
	"github.com/hyperledger/fabric/bccsp"
	"github.com/hyperledger/fabric/bccsp/utils"
	errors "github.com/pkg/errors"
)

func (msp *bccspmsp) getCertifiersIdentifier(certRaw []byte) ([]byte, error) {
	// 1. check that certificate is registered in msp.rootCerts or msp.intermediateCerts
	cert, err := msp.getCertFromPem(certRaw)
	if err != nil {
		return nil, fmt.Errorf("Failed getting certificate for [%v]: [%s]", certRaw, err)
	}

	// 2. Sanitize it to ensure like for like comparison
	cert, err = msp.sanitizeCert(cert)
	if err != nil {
		return nil, fmt.Errorf("sanitizeCert failed %s", err)
	}

	found := false
	root := false
	// Search among root certificates
	for _, v := range msp.rootCerts {
		if v.(*identity).cert.Equal(cert) {
			found = true
			root = true
			break
		}
	}
	if !found {
		// Search among root intermediate certificates
		for _, v := range msp.intermediateCerts {
			if v.(*identity).cert.Equal(cert) {
				found = true
				break
			}
		}
	}
	if !found {
		// Certificate not valid, reject configuration
		return nil, fmt.Errorf("Failed adding OU. Certificate [%v] not in root or intermediate certs.", cert)
	}

	// 3. get the certification path for it
	var certifiersIdentifier []byte
	var chain []*x509.Certificate
	if root {
		chain = []*x509.Certificate{cert}
	} else {
		chain, err = msp.getValidationChain(cert, true)
		if err != nil {
			return nil, fmt.Errorf("Failed computing validation chain for [%v]. [%s]", cert, err)
		}
	}

	// 4. compute the hash of the certification path
	certifiersIdentifier, err = msp.getCertificationChainIdentifierFromChain(chain)
	if err != nil {
		return nil, fmt.Errorf("Failed computing Certifiers Identifier for [%v]. [%s]", certRaw, err)
	}

	return certifiersIdentifier, nil
}

func (msp *bccspmsp) setupCrypto(conf *m.FabricMSPConfig) error {
	msp.cryptoConfig = conf.CryptoConfig
	if msp.cryptoConfig == nil {
		// Move to defaults
		msp.cryptoConfig = &m.FabricCryptoConfig{
			SignatureHashFamily:            bccsp.SHA2,
			IdentityIdentifierHashFunction: bccsp.SHA256,
		}
		mspLogger.Debugf("CryptoConfig was nil. Move to defaults.")
	}
	if msp.cryptoConfig.SignatureHashFamily == "" {
		msp.cryptoConfig.SignatureHashFamily = bccsp.SHA2
		mspLogger.Debugf("CryptoConfig.SignatureHashFamily was nil. Move to defaults.")
	}
	if msp.cryptoConfig.IdentityIdentifierHashFunction == "" {
		msp.cryptoConfig.IdentityIdentifierHashFunction = bccsp.SHA256
		mspLogger.Debugf("CryptoConfig.IdentityIdentifierHashFunction was nil. Move to defaults.")
	}

	return nil
}

func (msp *bccspmsp) setupCAs(conf *m.FabricMSPConfig) error {
	// make and fill the set of CA certs - we expect them to be there
	if len(conf.RootCerts) == 0 {
		return errors.New("expected at least one CA certificate")
	}

	// pre-create the verify options with roots and intermediates.
	// This is needed to make certificate sanitation working.
	// Recall that sanitization is applied also to root CA and intermediate
	// CA certificates. After their sanitization is done, the opts
	// will be recreated using the sanitized certs.
	msp.opts = &x509.VerifyOptions{Roots: x509.NewCertPool(), Intermediates: x509.NewCertPool()}
	for _, v := range conf.RootCerts {
		cert, err := msp.getCertFromPem(v)
		if err != nil {
			return err
		}
		msp.opts.Roots.AddCert(cert)
	}
	for _, v := range conf.IntermediateCerts {
		cert, err := msp.getCertFromPem(v)
		if err != nil {
			return err
		}
		msp.opts.Intermediates.AddCert(cert)
	}

	// Load root and intermediate CA identities
	// Recall that when an identity is created, its certificate gets sanitized
	msp.rootCerts = make([]Identity, len(conf.RootCerts))
	for i, trustedCert := range conf.RootCerts {
		id, _, err := msp.getIdentityFromConf(trustedCert)
		if err != nil {
			return err
		}

		msp.rootCerts[i] = id
	}

	// make and fill the set of intermediate certs (if present)
	msp.intermediateCerts = make([]Identity, len(conf.IntermediateCerts))
	for i, trustedCert := range conf.IntermediateCerts {
		id, _, err := msp.getIdentityFromConf(trustedCert)
		if err != nil {
			return err
		}

		msp.intermediateCerts[i] = id
	}

	// root CA and intermediate CA certificates are sanitized, they can be re-imported
	msp.opts = &x509.VerifyOptions{Roots: x509.NewCertPool(), Intermediates: x509.NewCertPool()}
	for _, id := range msp.rootCerts {
		msp.opts.Roots.AddCert(id.(*identity).cert)
	}
	for _, id := range msp.intermediateCerts {
		msp.opts.Intermediates.AddCert(id.(*identity).cert)
	}

	return nil
}

func (msp *bccspmsp) setupAdmins(conf *m.FabricMSPConfig) error {
	return msp.internalSetupAdmin(conf)
}

func (msp *bccspmsp) setupAdminsPreV142(conf *m.FabricMSPConfig) error {
	// make and fill the set of admin certs (if present)
	msp.admins = make([]Identity, len(conf.Admins))
	for i, admCert := range conf.Admins {
		id, _, err := msp.getIdentityFromConf(admCert)
		if err != nil {
			return err
		}

		msp.admins[i] = id
	}

	return nil
}

func (msp *bccspmsp) setupAdminsV142(conf *m.FabricMSPConfig) error {
	// make and fill the set of admin certs (if present)
	if err := msp.setupAdminsPreV142(conf); err != nil {
		return err
	}

	if len(msp.admins) == 0 && (!msp.ouEnforcement || msp.adminOU == nil) {
		return errors.New("administrators must be declared when no admin ou classification is set")
	}

	return nil
}

func isECDSASignatureAlgorithm(algid asn1.ObjectIdentifier) bool {
	// This is the set of ECDSA algorithms supported by Go 1.14 for CRL
	// signatures.
	ecdsaSignaureAlgorithms := []asn1.ObjectIdentifier{
		{1, 2, 840, 10045, 4, 1},    // oidSignatureECDSAWithSHA1
		{1, 2, 840, 10045, 4, 3, 2}, // oidSignatureECDSAWithSHA256
		{1, 2, 840, 10045, 4, 3, 3}, // oidSignatureECDSAWithSHA384
		{1, 2, 840, 10045, 4, 3, 4}, // oidSignatureECDSAWithSHA512
	}
	for _, id := range ecdsaSignaureAlgorithms {
		if id.Equal(algid) {
			return true
		}
	}
	return false
}

func (msp *bccspmsp) setupCRLs(conf *m.FabricMSPConfig) error {
	// setup the CRL (if present)
	msp.CRL = make([]*pkix.CertificateList, len(conf.RevocationList))
	for i, crlbytes := range conf.RevocationList {
		crl, err := x509.ParseCRL(crlbytes)
		if err != nil {
			return errors.Wrap(err, "could not parse RevocationList")
		}

		// Massage the ECDSA signature values
		if isECDSASignatureAlgorithm(crl.SignatureAlgorithm.Algorithm) {
			r, s, err := utils.UnmarshalECDSASignature(crl.SignatureValue.RightAlign())
			if err != nil {
				return err
			}
			sig, err := utils.MarshalECDSASignature(r, s)
			if err != nil {
				return err
			}
			crl.SignatureValue = asn1.BitString{Bytes: sig, BitLength: 8 * len(sig)}
		}

		// TODO: pre-verify the signature on the CRL and create a map
		//       of CA certs to respective CRLs so that later upon
		//       validation we can already look up the CRL given the
		//       chain of the certificate to be validated

		msp.CRL[i] = crl
	}

	return nil
}

func (msp *bccspmsp) finalizeSetupCAs() error {
	// ensure that our CAs are properly formed and that they are valid
	for _, id := range append(append([]Identity{}, msp.rootCerts...), msp.intermediateCerts...) {
		if !id.(*identity).cert.IsCA {
			return errors.Errorf("CA Certificate did not have the CA attribute, (SN: %x)", id.(*identity).cert.SerialNumber)
		}
		if _, err := getSubjectKeyIdentifierFromCert(id.(*identity).cert); err != nil {
			return errors.WithMessagef(err, "CA Certificate problem with Subject Key Identifier extension, (SN: %x)", id.(*identity).cert.SerialNumber)
		}

		if err := msp.validateCAIdentity(id.(*identity)); err != nil {
			return errors.WithMessagef(err, "CA Certificate is not valid, (SN: %s)", id.(*identity).cert.SerialNumber)
		}
	}

	// populate certificationTreeInternalNodesMap to mark the internal nodes of the
	// certification tree
	msp.certificationTreeInternalNodesMap = make(map[string]bool)
	for _, id := range append([]Identity{}, msp.intermediateCerts...) {
		chain, err := msp.getUniqueValidationChain(id.(*identity).cert, msp.getValidityOptsForCert(id.(*identity).cert))
		if err != nil {
			return errors.WithMessagef(err, "failed getting validation chain, (SN: %s)", id.(*identity).cert.SerialNumber)
		}

		// Recall chain[0] is id.(*identity).id so it does not count as a parent
		for i := 1; i < len(chain); i++ {
			msp.certificationTreeInternalNodesMap[string(chain[i].Raw)] = true
		}
	}

	return nil
}

func (msp *bccspmsp) setupNodeOUs(config *m.FabricMSPConfig) error {
	if config.FabricNodeOus != nil {

		msp.ouEnforcement = config.FabricNodeOus.Enable

		if config.FabricNodeOus.ClientOuIdentifier == nil || len(config.FabricNodeOus.ClientOuIdentifier.OrganizationalUnitIdentifier) == 0 {
			return errors.New("Failed setting up NodeOUs. ClientOU must be different from nil.")
		}

		if config.FabricNodeOus.PeerOuIdentifier == nil || len(config.FabricNodeOus.PeerOuIdentifier.OrganizationalUnitIdentifier) == 0 {
			return errors.New("Failed setting up NodeOUs. PeerOU must be different from nil.")
		}

		// ClientOU
		msp.clientOU = &OUIdentifier{OrganizationalUnitIdentifier: config.FabricNodeOus.ClientOuIdentifier.OrganizationalUnitIdentifier}
		if len(config.FabricNodeOus.ClientOuIdentifier.Certificate) != 0 {
			certifiersIdentifier, err := msp.getCertifiersIdentifier(config.FabricNodeOus.ClientOuIdentifier.Certificate)
			if err != nil {
				return err
			}
			msp.clientOU.CertifiersIdentifier = certifiersIdentifier
		}

		// PeerOU
		msp.peerOU = &OUIdentifier{OrganizationalUnitIdentifier: config.FabricNodeOus.PeerOuIdentifier.OrganizationalUnitIdentifier}
		if len(config.FabricNodeOus.PeerOuIdentifier.Certificate) != 0 {
			certifiersIdentifier, err := msp.getCertifiersIdentifier(config.FabricNodeOus.PeerOuIdentifier.Certificate)
			if err != nil {
				return err
			}
			msp.peerOU.CertifiersIdentifier = certifiersIdentifier
		}

	} else {
		msp.ouEnforcement = false
	}

	return nil
}

func (msp *bccspmsp) setupNodeOUsV142(config *m.FabricMSPConfig) error {
	if config.FabricNodeOus == nil {
		msp.ouEnforcement = false
		return nil
	}

	msp.ouEnforcement = config.FabricNodeOus.Enable

	counter := 0
	// ClientOU
	if config.FabricNodeOus.ClientOuIdentifier != nil {
		msp.clientOU = &OUIdentifier{OrganizationalUnitIdentifier: config.FabricNodeOus.ClientOuIdentifier.OrganizationalUnitIdentifier}
		if len(config.FabricNodeOus.ClientOuIdentifier.Certificate) != 0 {
			certifiersIdentifier, err := msp.getCertifiersIdentifier(config.FabricNodeOus.ClientOuIdentifier.Certificate)
			if err != nil {
				return err
			}
			msp.clientOU.CertifiersIdentifier = certifiersIdentifier
		}
		counter++
	} else {
		msp.clientOU = nil
	}

	// PeerOU
	if config.FabricNodeOus.PeerOuIdentifier != nil {
		msp.peerOU = &OUIdentifier{OrganizationalUnitIdentifier: config.FabricNodeOus.PeerOuIdentifier.OrganizationalUnitIdentifier}
		if len(config.FabricNodeOus.PeerOuIdentifier.Certificate) != 0 {
			certifiersIdentifier, err := msp.getCertifiersIdentifier(config.FabricNodeOus.PeerOuIdentifier.Certificate)
			if err != nil {
				return err
			}
			msp.peerOU.CertifiersIdentifier = certifiersIdentifier
		}
		counter++
	} else {
		msp.peerOU = nil
	}

	// AdminOU
	if config.FabricNodeOus.AdminOuIdentifier != nil {
		msp.adminOU = &OUIdentifier{OrganizationalUnitIdentifier: config.FabricNodeOus.AdminOuIdentifier.OrganizationalUnitIdentifier}
		if len(config.FabricNodeOus.AdminOuIdentifier.Certificate) != 0 {
			certifiersIdentifier, err := msp.getCertifiersIdentifier(config.FabricNodeOus.AdminOuIdentifier.Certificate)
			if err != nil {
				return err
			}
			msp.adminOU.CertifiersIdentifier = certifiersIdentifier
		}
		counter++
	} else {
		msp.adminOU = nil
	}

	// OrdererOU
	if config.FabricNodeOus.OrdererOuIdentifier != nil {
		msp.ordererOU = &OUIdentifier{OrganizationalUnitIdentifier: config.FabricNodeOus.OrdererOuIdentifier.OrganizationalUnitIdentifier}
		if len(config.FabricNodeOus.OrdererOuIdentifier.Certificate) != 0 {
			certifiersIdentifier, err := msp.getCertifiersIdentifier(config.FabricNodeOus.OrdererOuIdentifier.Certificate)
			if err != nil {
				return err
			}
			msp.ordererOU.CertifiersIdentifier = certifiersIdentifier
		}
		counter++
	} else {
		msp.ordererOU = nil
	}

	if counter == 0 {
		// Disable NodeOU
		msp.ouEnforcement = false
	}

	return nil
}

func (msp *bccspmsp) setupSigningIdentity(conf *m.FabricMSPConfig) error {
	if conf.SigningIdentity != nil {
		sid, err := msp.getSigningIdentityFromConf(conf.SigningIdentity)
		if err != nil {
			return err
		}

		expirationTime := sid.ExpiresAt()
		now := time.Now()
		if expirationTime.After(now) {
			mspLogger.Debug("Signing identity expires at", expirationTime)
		} else if expirationTime.IsZero() {
			mspLogger.Debug("Signing identity has no known expiration time")
		} else {
			return errors.Errorf("signing identity expired %v ago", now.Sub(expirationTime))
		}

		msp.signer = sid
	}

	return nil
}

func (msp *bccspmsp) setupOUs(conf *m.FabricMSPConfig) error {
	msp.ouIdentifiers = make(map[string][][]byte)
	for _, ou := range conf.OrganizationalUnitIdentifiers {

		certifiersIdentifier, err := msp.getCertifiersIdentifier(ou.Certificate)
		if err != nil {
			return errors.WithMessagef(err, "failed getting certificate for [%v]", ou)
		}

		// Check for duplicates
		found := false
		for _, id := range msp.ouIdentifiers[ou.OrganizationalUnitIdentifier] {
			if bytes.Equal(id, certifiersIdentifier) {
				mspLogger.Warningf("Duplicate found in ou identifiers [%s, %v]", ou.OrganizationalUnitIdentifier, id)
				found = true
				break
			}
		}

		if !found {
			// No duplicates found, add it
			msp.ouIdentifiers[ou.OrganizationalUnitIdentifier] = append(
				msp.ouIdentifiers[ou.OrganizationalUnitIdentifier],
				certifiersIdentifier,
			)
		}
	}

	return nil
}

func (msp *bccspmsp) setupTLSCAs(conf *m.FabricMSPConfig) error {
	opts := &x509.VerifyOptions{Roots: x509.NewCertPool(), Intermediates: x509.NewCertPool()}

	// Load TLS root and intermediate CA identities
	msp.tlsRootCerts = make([][]byte, len(conf.TlsRootCerts))
	rootCerts := make([]*x509.Certificate, len(conf.TlsRootCerts))
	for i, trustedCert := range conf.TlsRootCerts {
		cert, err := msp.getCertFromPem(trustedCert)
		if err != nil {
			return err
		}

		rootCerts[i] = cert
		msp.tlsRootCerts[i] = trustedCert
		opts.Roots.AddCert(cert)
	}

	// make and fill the set of intermediate certs (if present)
	msp.tlsIntermediateCerts = make([][]byte, len(conf.TlsIntermediateCerts))
	intermediateCerts := make([]*x509.Certificate, len(conf.TlsIntermediateCerts))
	for i, trustedCert := range conf.TlsIntermediateCerts {
		cert, err := msp.getCertFromPem(trustedCert)
		if err != nil {
			return err
		}

		intermediateCerts[i] = cert
		msp.tlsIntermediateCerts[i] = trustedCert
		opts.Intermediates.AddCert(cert)
	}

	// ensure that our CAs are properly formed and that they are valid
	for _, cert := range append(append([]*x509.Certificate{}, rootCerts...), intermediateCerts...) {
		if cert == nil {
			continue
		}

		if !cert.IsCA {
			return errors.Errorf("CA Certificate did not have the CA attribute, (SN: %x)", cert.SerialNumber)
		}
		if _, err := getSubjectKeyIdentifierFromCert(cert); err != nil {
			return errors.WithMessagef(err, "CA Certificate problem with Subject Key Identifier extension, (SN: %x)", cert.SerialNumber)
		}

		if err := msp.validateTLSCAIdentity(cert, opts); err != nil {
			return errors.WithMessagef(err, "CA Certificate is not valid, (SN: %s)", cert.SerialNumber)
		}
	}

	return nil
}

func (msp *bccspmsp) setupV1(conf1 *m.FabricMSPConfig) error {
	err := msp.preSetupV1(conf1)
	if err != nil {
		return err
	}

	err = msp.postSetupV1(conf1)
	if err != nil {
		return err
	}

	return nil
}

func (msp *bccspmsp) preSetupV1(conf *m.FabricMSPConfig) error {
	// setup crypto config
	if err := msp.setupCrypto(conf); err != nil {
		return err
	}

	// Setup CAs
	if err := msp.setupCAs(conf); err != nil {
		return err
	}

	// Setup Admins
	if err := msp.setupAdmins(conf); err != nil {
		return err
	}

	// Setup CRLs
	if err := msp.setupCRLs(conf); err != nil {
		return err
	}

	// Finalize setup of the CAs
	if err := msp.finalizeSetupCAs(); err != nil {
		return err
	}

	// setup the signer (if present)
	if err := msp.setupSigningIdentity(conf); err != nil {
		return err
	}

	// setup TLS CAs
	if err := msp.setupTLSCAs(conf); err != nil {
		return err
	}

	// setup the OUs
	if err := msp.setupOUs(conf); err != nil {
		return err
	}

	return nil
}

func (msp *bccspmsp) preSetupV142(conf *m.FabricMSPConfig) error {
	// setup crypto config
	if err := msp.setupCrypto(conf); err != nil {
		return err
	}

	// Setup CAs
	if err := msp.setupCAs(conf); err != nil {
		return err
	}

	// Setup CRLs
	if err := msp.setupCRLs(conf); err != nil {
		return err
	}

	// Finalize setup of the CAs
	if err := msp.finalizeSetupCAs(); err != nil {
		return err
	}

	// setup the signer (if present)
	if err := msp.setupSigningIdentity(conf); err != nil {
		return err
	}

	// setup TLS CAs
	if err := msp.setupTLSCAs(conf); err != nil {
		return err
	}

	// setup the OUs
	if err := msp.setupOUs(conf); err != nil {
		return err
	}

	// setup NodeOUs
	if err := msp.setupNodeOUsV142(conf); err != nil {
		return err
	}

	// Setup Admins
	if err := msp.setupAdmins(conf); err != nil {
		return err
	}

	return nil
}

func (msp *bccspmsp) postSetupV1(conf *m.FabricMSPConfig) error {
	// make sure that admins are valid members as well
	// this way, when we validate an admin MSP principal
	// we can simply check for exact match of certs
	for i, admin := range msp.admins {
		err := admin.Validate()
		if err != nil {
			return errors.WithMessagef(err, "admin %d is invalid", i)
		}
	}

	return nil
}

func (msp *bccspmsp) setupV11(conf *m.FabricMSPConfig) error {
	err := msp.preSetupV1(conf)
	if err != nil {
		return err
	}

	// setup NodeOUs
	if err := msp.setupNodeOUs(conf); err != nil {
		return err
	}

	err = msp.postSetupV11(conf)
	if err != nil {
		return err
	}

	return nil
}

func (msp *bccspmsp) setupV142(conf *m.FabricMSPConfig) error {
	err := msp.preSetupV142(conf)
	if err != nil {
		return err
	}

	err = msp.postSetupV142(conf)
	if err != nil {
		return err
	}

	return nil
}

func (msp *bccspmsp) postSetupV11(conf *m.FabricMSPConfig) error {
	// Check for OU enforcement
	if !msp.ouEnforcement {
		// No enforcement required. Call post setup as per V1
		return msp.postSetupV1(conf)
	}

	// Check that admins are clients
	principalBytes, err := proto.Marshal(&m.MSPRole{Role: m.MSPRole_CLIENT, MspIdentifier: msp.name})
	if err != nil {
		return errors.Wrapf(err, "failed creating MSPRole_CLIENT")
	}
	principal := &m.MSPPrincipal{
		PrincipalClassification: m.MSPPrincipal_ROLE,
		Principal:               principalBytes,
	}
	for i, admin := range msp.admins {
		err = admin.SatisfiesPrincipal(principal)
		if err != nil {
			return errors.WithMessagef(err, "admin %d is invalid", i)
		}
	}

	return nil
}

func (msp *bccspmsp) postSetupV142(conf *m.FabricMSPConfig) error {
	// Check for OU enforcement
	if !msp.ouEnforcement {
		// No enforcement required. Call post setup as per V1
		return msp.postSetupV1(conf)
	}

	// Check that admins are clients or admins
	for i, admin := range msp.admins {
		err1 := msp.hasOURole(admin, m.MSPRole_CLIENT)
		err2 := msp.hasOURole(admin, m.MSPRole_ADMIN)
		if err1 != nil && err2 != nil {
			return errors.Errorf("admin %d is invalid [%s,%s]", i, err1, err2)
		}
	}

	return nil
}

redpajama_set_name: RedPajamaGithub


text:
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html
    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">

  <title>Qt 4.3: Qt 3 Compatibility Classes</title>
  <link href="classic.css" rel="stylesheet" type="text/css" />

  	Home · All Classes · Main Classes · Grouped Classes · Modules · Functions

Qt 3 Compatibility Classes

This is a list of the classes that Qt provides for compatibility with Qt 3. The vast majority of these are provided by the Qt3Support module.

3
Q3Accel

Q3DataBrowser

Q3IconDrag

Q3PtrCollection

Q3TabDialog

Q3Action

Q3DataTable

Q3IconDragItem

Q3PtrDict

Q3Table

Q3ActionGroup

Q3DataView

Q3IconView

Q3PtrDictIterator

Q3TableItem

Q3AsciiCache

Q3DateEdit

Q3IconViewItem

Q3PtrList

Q3TableSelection

Q3AsciiCacheIterator

Q3DateTimeEdit

Q3ImageDrag

Q3PtrListIterator

Q3TextBrowser

Q3AsciiDict

Q3DateTimeEditBase

Q3IntCache

Q3PtrQueue

Q3TextDrag

Q3AsciiDictIterator

Q3DeepCopy

Q3IntCacheIterator

Q3PtrStack

Q3TextEdit

Q3Button

Q3Dict

Q3IntDict

Q3PtrVector

Q3TextStream

Q3ButtonGroup

Q3DictIterator

Q3IntDictIterator

Q3RangeControl

Q3TextView

Q3Cache

Q3Dns

Q3ListBox

Q3ScrollView

Q3TimeEdit

Q3CacheIterator

Q3DockArea

Q3ListBoxItem

Q3Semaphore

Q3ToolBar

Q3Canvas

Q3DockWindow

Q3ListBoxPixmap

Q3ServerSocket

Q3UriDrag

Q3CanvasEllipse

Q3DragObject

Q3ListBoxText

Q3Shared

Q3Url

Q3CanvasItem

Q3DropSite

Q3ListView

Q3Signal

Q3UrlOperator

Q3CanvasItemList

Q3EditorFactory

Q3ListViewItem

Q3SimpleRichText

Q3ValueList

Q3CanvasLine

Q3FileDialog

Q3ListViewItemIterator

Q3Socket

Q3ValueListConstIterator

Q3CanvasPixmap

Q3FileIconProvider

Q3LocalFs

Q3SocketDevice

Q3ValueListIterator

Q3CanvasPixmapArray

Q3FilePreview

Q3MainWindow

Q3SqlCursor

Q3ValueStack

Q3CanvasPolygon

Q3Frame

Q3MemArray

Q3SqlEditorFactory

Q3ValueVector

Q3CanvasPolygonalItem

Q3Ftp

Q3MimeSourceFactory

Q3SqlFieldInfo

Q3VBox

Q3CanvasRectangle

Q3Grid

Q3MultiLineEdit

Q3SqlForm

Q3VButtonGroup

Q3CanvasSpline

Q3GridView

Q3NetworkOperation

Q3SqlPropertyMap

Q3VGroupBox

Q3CanvasSprite

Q3GroupBox

Q3NetworkProtocol

Q3SqlRecordInfo

Q3WhatsThis

Q3CanvasText

Q3HBox

Q3PaintDeviceMetrics

Q3SqlSelectCursor

Q3WidgetStack

Q3CanvasView

Q3HButtonGroup

Q3Painter

Q3StoredDrag

Q3Wizard

Q3CheckListItem

Q3Header

Q3Picture

Q3StrIList
C
QColorGroup

Q3CheckTableItem

Q3HGroupBox

Q3PointArray

Q3StrList

QConstString

Q3ColorDrag

Q3Http

Q3PopupMenu

Q3StrListIterator

QCustomEvent

Q3ComboBox

Q3HttpHeader

Q3Process

Q3StyleSheet
M
QMenuItem

Q3ComboTableItem

Q3HttpRequestHeader

Q3ProgressBar

Q3StyleSheetItem
T
QTextIStream

Q3CString

Q3HttpResponseHeader

Q3ProgressDialog

Q3SyntaxHighlighter

QTextOStream

See also Qt's Classes and Qt's Modules.

<address>

Copyright © 2008 Trolltech
Trademarks

Qt 4.3.5

</address>


text:
/**
 * Created by
 * Group 50
 *
 * Varun Simha Balaraju
 * Venkata Sarath Chandra Prasad Nelapati
 * Jithin Paul
 * Sunit Mathew
 **/

package cs6301.g50;

import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;

public final class HuffmanCoding {
    private static final int SIZE = 256;

    /*
    * Huffman result class that is used to give external functions the Huffman tree or the result
    *
    * */
    public static final class HuffResult{
        private final String encoded;
        private final HuffmanNode mapping;
        private final Map<Character, String> lookupTable;

        HuffResult(String encoded, HuffmanNode mapping, Map<Character, String> lookupTable) {
            this.encoded = encoded;
            this.mapping = mapping;
            this.lookupTable = lookupTable;
        }

        public String toString(){
            return this.encoded;
        }

        public HuffmanNode getMapping(){
            return this.mapping;
        }

        public Map<Character, String> getLookupTable(){
            return this.lookupTable;
        }
    }

    /*
    * Class that is the building block of a Huffman Tree
    *
    * */
    private static class HuffmanNode implements Comparable<HuffmanNode>{
        char ch;
        int frequency;
        HuffmanNode left;
        HuffmanNode right;

        HuffmanNode(char ch, int frequency,  HuffmanNode left,  HuffmanNode right) {
            this.ch = ch;
            this.frequency = frequency;
            this.left = left;
            this.right = right;
        }

        public int compareTo(HuffmanNode huffmanNode) {
            return this.frequency>huffmanNode.frequency?1:(this.frequency<huffmanNode.frequency?-1:0);
        }

        public boolean isLeaf() {
            return null==left&&null==right;
        }
    }

    /*
    * Function to build a Frequency map given an input sentence
    *
    * */
    private static int[] getFrequencyMap(String sentence) {
        final int[] map = new int[SIZE];
        for (int i = 0; i < sentence.length(); i++) {
            char ch = sentence.charAt(i);
            map[ch]++;
        }
        return map;
    }

    /*
    * Function to build a Huffman Tree given a frequency map
    *
    * */
    private static HuffmanNode buildHuffmanTree(int[] map){
        final PriorityQueue<HuffmanNode> priorityQueue = new PriorityQueue<>();
        for(char i=0; i<SIZE; i++){
            if(map[i]>0){
                priorityQueue.add(new HuffmanNode(i, map[i],null,null));
            }
        }

        while (priorityQueue.size()>1){
            final HuffmanNode left = priorityQueue.poll();
            final HuffmanNode right = priorityQueue.poll();
            final HuffmanNode parent = new HuffmanNode('\0',left.frequency+right.frequency,left,right);
            priorityQueue.add(parent);
        }

        return priorityQueue.poll();
    }

    /*
    * Function to build a lookup table given a Huffman tree
    *
    * */
    private static Map<Character, String> buildLookupTable(final HuffmanNode root){
        final Map<Character, String> lookupTable = new HashMap<>();
        buildLookupTableImpl(root,"",lookupTable);
        return lookupTable;
    }

    /*
    * Implementation function to build a lookup table, given a Huffman tree
    *
    * */
    private static void buildLookupTableImpl(final HuffmanNode root, final String s, final Map<Character, String> lookupTable) {
        if(!root.isLeaf()){
            buildLookupTableImpl(root.left,s+'0',lookupTable);
            buildLookupTableImpl(root.right,s+'1',lookupTable);
        }else{
            lookupTable.put(root.ch, s);
        }
    }

    /*
    * Function to encodeData given a string and a created lookupTable
    *
    * */
    private String encodeData(final String input, final Map<Character, String> lookupTable){
        final StringBuilder builder = new StringBuilder();
        for(final char ch:input.toCharArray()){
            String encoded = lookupTable.get(ch);
            builder.append(encoded);
        }
        return builder.toString();
    }

    /*
    * Function to encode a message given String
    *
    * */
    public HuffResult encode(final String input){
        final int[] map  = getFrequencyMap(input);
        final HuffmanNode huffTree = buildHuffmanTree(map);
        final Map<Character, String> lookupTable = buildLookupTable(huffTree);
        return new HuffResult(encodeData(input,lookupTable),huffTree,lookupTable);
    }

    /*
    * Function to decode a message given a Huffman Tree
    *
    * */
    public String decodeMessage(String input, HuffmanNode node){
        final StringBuilder builder = new StringBuilder();
        final char[] charArray = input.toCharArray();
        for (int i = 0; i < charArray.length;) {
            HuffmanNode temp = node;
            while (temp.left != null) {
                if (charArray[i]=='0') {
                    temp = temp.left;
                } else {
                    temp = temp.right;
                }
                i = i + 1;
            }
            builder.append(temp.ch);
        }
        return builder.toString();
    }
}


text:
package storsimple

// Copyright (c) Microsoft and contributors.  All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.

import (
	"context"
	"github.com/Azure/go-autorest/autorest"
	"github.com/Azure/go-autorest/autorest/azure"
	"github.com/Azure/go-autorest/autorest/validation"
	"github.com/Azure/go-autorest/tracing"
	"net/http"
)

// DevicesClient is the client for the Devices methods of the Storsimple service.
type DevicesClient struct {
	BaseClient
}

// NewDevicesClient creates an instance of the DevicesClient client.
func NewDevicesClient(subscriptionID string) DevicesClient {
	return NewDevicesClientWithBaseURI(DefaultBaseURI, subscriptionID)
}

// NewDevicesClientWithBaseURI creates an instance of the DevicesClient client.
func NewDevicesClientWithBaseURI(baseURI string, subscriptionID string) DevicesClient {
	return DevicesClient{NewWithBaseURI(baseURI, subscriptionID)}
}

// AuthorizeForServiceEncryptionKeyRollover authorizes the specified device for service data encryption key rollover.
// Parameters:
// deviceName - the device name
// resourceGroupName - the resource group name
// managerName - the manager name
func (client DevicesClient) AuthorizeForServiceEncryptionKeyRollover(ctx context.Context, deviceName string, resourceGroupName string, managerName string) (result autorest.Response, err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/DevicesClient.AuthorizeForServiceEncryptionKeyRollover")
		defer func() {
			sc := -1
			if result.Response != nil {
				sc = result.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	if err := validation.Validate([]validation.Validation{
		{TargetValue: managerName,
			Constraints: []validation.Constraint{{Target: "managerName", Name: validation.MaxLength, Rule: 50, Chain: nil},
				{Target: "managerName", Name: validation.MinLength, Rule: 2, Chain: nil}}}}); err != nil {
		return result, validation.NewError("storsimple.DevicesClient", "AuthorizeForServiceEncryptionKeyRollover", err.Error())
	}

	req, err := client.AuthorizeForServiceEncryptionKeyRolloverPreparer(ctx, deviceName, resourceGroupName, managerName)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "AuthorizeForServiceEncryptionKeyRollover", nil, "Failure preparing request")
		return
	}

	resp, err := client.AuthorizeForServiceEncryptionKeyRolloverSender(req)
	if err != nil {
		result.Response = resp
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "AuthorizeForServiceEncryptionKeyRollover", resp, "Failure sending request")
		return
	}

	result, err = client.AuthorizeForServiceEncryptionKeyRolloverResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "AuthorizeForServiceEncryptionKeyRollover", resp, "Failure responding to request")
	}

	return
}

// AuthorizeForServiceEncryptionKeyRolloverPreparer prepares the AuthorizeForServiceEncryptionKeyRollover request.
func (client DevicesClient) AuthorizeForServiceEncryptionKeyRolloverPreparer(ctx context.Context, deviceName string, resourceGroupName string, managerName string) (*http.Request, error) {
	pathParameters := map[string]interface{}{
		"deviceName":        deviceName,
		"managerName":       managerName,
		"resourceGroupName": resourceGroupName,
		"subscriptionId":    client.SubscriptionID,
	}

	const APIVersion = "2017-06-01"
	queryParameters := map[string]interface{}{
		"api-version": APIVersion,
	}

	preparer := autorest.CreatePreparer(
		autorest.AsPost(),
		autorest.WithBaseURL(client.BaseURI),
		autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.StorSimple/managers/{managerName}/devices/{deviceName}/authorizeForServiceEncryptionKeyRollover", pathParameters),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// AuthorizeForServiceEncryptionKeyRolloverSender sends the AuthorizeForServiceEncryptionKeyRollover request. The method will close the
// http.Response Body if it receives an error.
func (client DevicesClient) AuthorizeForServiceEncryptionKeyRolloverSender(req *http.Request) (*http.Response, error) {
	sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client))
	return autorest.SendWithSender(client, req, sd...)
}

// AuthorizeForServiceEncryptionKeyRolloverResponder handles the response to the AuthorizeForServiceEncryptionKeyRollover request. The method always
// closes the http.Response Body.
func (client DevicesClient) AuthorizeForServiceEncryptionKeyRolloverResponder(resp *http.Response) (result autorest.Response, err error) {
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent),
		autorest.ByClosing())
	result.Response = resp
	return
}

// Configure complete minimal setup before using the device.
// Parameters:
// parameters - the minimal properties to configure a device.
// resourceGroupName - the resource group name
// managerName - the manager name
func (client DevicesClient) Configure(ctx context.Context, parameters ConfigureDeviceRequest, resourceGroupName string, managerName string) (result DevicesConfigureFuture, err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/DevicesClient.Configure")
		defer func() {
			sc := -1
			if result.Response() != nil {
				sc = result.Response().StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	if err := validation.Validate([]validation.Validation{
		{TargetValue: parameters,
			Constraints: []validation.Constraint{{Target: "parameters.ConfigureDeviceRequestProperties", Name: validation.Null, Rule: true,
				Chain: []validation.Constraint{{Target: "parameters.ConfigureDeviceRequestProperties.FriendlyName", Name: validation.Null, Rule: true, Chain: nil},
					{Target: "parameters.ConfigureDeviceRequestProperties.CurrentDeviceName", Name: validation.Null, Rule: true, Chain: nil},
					{Target: "parameters.ConfigureDeviceRequestProperties.TimeZone", Name: validation.Null, Rule: true, Chain: nil},
				}}}},
		{TargetValue: managerName,
			Constraints: []validation.Constraint{{Target: "managerName", Name: validation.MaxLength, Rule: 50, Chain: nil},
				{Target: "managerName", Name: validation.MinLength, Rule: 2, Chain: nil}}}}); err != nil {
		return result, validation.NewError("storsimple.DevicesClient", "Configure", err.Error())
	}

	req, err := client.ConfigurePreparer(ctx, parameters, resourceGroupName, managerName)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "Configure", nil, "Failure preparing request")
		return
	}

	result, err = client.ConfigureSender(req)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "Configure", result.Response(), "Failure sending request")
		return
	}

	return
}

// ConfigurePreparer prepares the Configure request.
func (client DevicesClient) ConfigurePreparer(ctx context.Context, parameters ConfigureDeviceRequest, resourceGroupName string, managerName string) (*http.Request, error) {
	pathParameters := map[string]interface{}{
		"managerName":       managerName,
		"resourceGroupName": resourceGroupName,
		"subscriptionId":    client.SubscriptionID,
	}

	const APIVersion = "2017-06-01"
	queryParameters := map[string]interface{}{
		"api-version": APIVersion,
	}

	preparer := autorest.CreatePreparer(
		autorest.AsContentType("application/json; charset=utf-8"),
		autorest.AsPost(),
		autorest.WithBaseURL(client.BaseURI),
		autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.StorSimple/managers/{managerName}/configureDevice", pathParameters),
		autorest.WithJSON(parameters),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// ConfigureSender sends the Configure request. The method will close the
// http.Response Body if it receives an error.
func (client DevicesClient) ConfigureSender(req *http.Request) (future DevicesConfigureFuture, err error) {
	sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client))
	var resp *http.Response
	resp, err = autorest.SendWithSender(client, req, sd...)
	if err != nil {
		return
	}
	future.Future, err = azure.NewFutureFromResponse(resp)
	return
}

// ConfigureResponder handles the response to the Configure request. The method always
// closes the http.Response Body.
func (client DevicesClient) ConfigureResponder(resp *http.Response) (result autorest.Response, err error) {
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent),
		autorest.ByClosing())
	result.Response = resp
	return
}

// Deactivate deactivates the device.
// Parameters:
// deviceName - the device name
// resourceGroupName - the resource group name
// managerName - the manager name
func (client DevicesClient) Deactivate(ctx context.Context, deviceName string, resourceGroupName string, managerName string) (result DevicesDeactivateFuture, err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/DevicesClient.Deactivate")
		defer func() {
			sc := -1
			if result.Response() != nil {
				sc = result.Response().StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	if err := validation.Validate([]validation.Validation{
		{TargetValue: managerName,
			Constraints: []validation.Constraint{{Target: "managerName", Name: validation.MaxLength, Rule: 50, Chain: nil},
				{Target: "managerName", Name: validation.MinLength, Rule: 2, Chain: nil}}}}); err != nil {
		return result, validation.NewError("storsimple.DevicesClient", "Deactivate", err.Error())
	}

	req, err := client.DeactivatePreparer(ctx, deviceName, resourceGroupName, managerName)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "Deactivate", nil, "Failure preparing request")
		return
	}

	result, err = client.DeactivateSender(req)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "Deactivate", result.Response(), "Failure sending request")
		return
	}

	return
}

// DeactivatePreparer prepares the Deactivate request.
func (client DevicesClient) DeactivatePreparer(ctx context.Context, deviceName string, resourceGroupName string, managerName string) (*http.Request, error) {
	pathParameters := map[string]interface{}{
		"deviceName":        deviceName,
		"managerName":       managerName,
		"resourceGroupName": resourceGroupName,
		"subscriptionId":    client.SubscriptionID,
	}

	const APIVersion = "2017-06-01"
	queryParameters := map[string]interface{}{
		"api-version": APIVersion,
	}

	preparer := autorest.CreatePreparer(
		autorest.AsPost(),
		autorest.WithBaseURL(client.BaseURI),
		autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.StorSimple/managers/{managerName}/devices/{deviceName}/deactivate", pathParameters),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// DeactivateSender sends the Deactivate request. The method will close the
// http.Response Body if it receives an error.
func (client DevicesClient) DeactivateSender(req *http.Request) (future DevicesDeactivateFuture, err error) {
	sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client))
	var resp *http.Response
	resp, err = autorest.SendWithSender(client, req, sd...)
	if err != nil {
		return
	}
	future.Future, err = azure.NewFutureFromResponse(resp)
	return
}

// DeactivateResponder handles the response to the Deactivate request. The method always
// closes the http.Response Body.
func (client DevicesClient) DeactivateResponder(resp *http.Response) (result autorest.Response, err error) {
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent),
		autorest.ByClosing())
	result.Response = resp
	return
}

// Delete deletes the device.
// Parameters:
// deviceName - the device name
// resourceGroupName - the resource group name
// managerName - the manager name
func (client DevicesClient) Delete(ctx context.Context, deviceName string, resourceGroupName string, managerName string) (result DevicesDeleteFuture, err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/DevicesClient.Delete")
		defer func() {
			sc := -1
			if result.Response() != nil {
				sc = result.Response().StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	if err := validation.Validate([]validation.Validation{
		{TargetValue: managerName,
			Constraints: []validation.Constraint{{Target: "managerName", Name: validation.MaxLength, Rule: 50, Chain: nil},
				{Target: "managerName", Name: validation.MinLength, Rule: 2, Chain: nil}}}}); err != nil {
		return result, validation.NewError("storsimple.DevicesClient", "Delete", err.Error())
	}

	req, err := client.DeletePreparer(ctx, deviceName, resourceGroupName, managerName)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "Delete", nil, "Failure preparing request")
		return
	}

	result, err = client.DeleteSender(req)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "Delete", result.Response(), "Failure sending request")
		return
	}

	return
}

// DeletePreparer prepares the Delete request.
func (client DevicesClient) DeletePreparer(ctx context.Context, deviceName string, resourceGroupName string, managerName string) (*http.Request, error) {
	pathParameters := map[string]interface{}{
		"deviceName":        deviceName,
		"managerName":       managerName,
		"resourceGroupName": resourceGroupName,
		"subscriptionId":    client.SubscriptionID,
	}

	const APIVersion = "2017-06-01"
	queryParameters := map[string]interface{}{
		"api-version": APIVersion,
	}

	preparer := autorest.CreatePreparer(
		autorest.AsDelete(),
		autorest.WithBaseURL(client.BaseURI),
		autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.StorSimple/managers/{managerName}/devices/{deviceName}", pathParameters),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// DeleteSender sends the Delete request. The method will close the
// http.Response Body if it receives an error.
func (client DevicesClient) DeleteSender(req *http.Request) (future DevicesDeleteFuture, err error) {
	sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client))
	var resp *http.Response
	resp, err = autorest.SendWithSender(client, req, sd...)
	if err != nil {
		return
	}
	future.Future, err = azure.NewFutureFromResponse(resp)
	return
}

// DeleteResponder handles the response to the Delete request. The method always
// closes the http.Response Body.
func (client DevicesClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) {
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent),
		autorest.ByClosing())
	result.Response = resp
	return
}

// Failover failovers a set of volume containers from a specified source device to a target device.
// Parameters:
// sourceDeviceName - the source device name on which failover is performed.
// parameters - failoverRequest containing the source device and the list of volume containers to be failed
// over.
// resourceGroupName - the resource group name
// managerName - the manager name
func (client DevicesClient) Failover(ctx context.Context, sourceDeviceName string, parameters FailoverRequest, resourceGroupName string, managerName string) (result DevicesFailoverFuture, err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/DevicesClient.Failover")
		defer func() {
			sc := -1
			if result.Response() != nil {
				sc = result.Response().StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	if err := validation.Validate([]validation.Validation{
		{TargetValue: managerName,
			Constraints: []validation.Constraint{{Target: "managerName", Name: validation.MaxLength, Rule: 50, Chain: nil},
				{Target: "managerName", Name: validation.MinLength, Rule: 2, Chain: nil}}}}); err != nil {
		return result, validation.NewError("storsimple.DevicesClient", "Failover", err.Error())
	}

	req, err := client.FailoverPreparer(ctx, sourceDeviceName, parameters, resourceGroupName, managerName)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "Failover", nil, "Failure preparing request")
		return
	}

	result, err = client.FailoverSender(req)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "Failover", result.Response(), "Failure sending request")
		return
	}

	return
}

// FailoverPreparer prepares the Failover request.
func (client DevicesClient) FailoverPreparer(ctx context.Context, sourceDeviceName string, parameters FailoverRequest, resourceGroupName string, managerName string) (*http.Request, error) {
	pathParameters := map[string]interface{}{
		"managerName":       managerName,
		"resourceGroupName": resourceGroupName,
		"sourceDeviceName":  sourceDeviceName,
		"subscriptionId":    client.SubscriptionID,
	}

	const APIVersion = "2017-06-01"
	queryParameters := map[string]interface{}{
		"api-version": APIVersion,
	}

	preparer := autorest.CreatePreparer(
		autorest.AsContentType("application/json; charset=utf-8"),
		autorest.AsPost(),
		autorest.WithBaseURL(client.BaseURI),
		autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.StorSimple/managers/{managerName}/devices/{sourceDeviceName}/failover", pathParameters),
		autorest.WithJSON(parameters),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// FailoverSender sends the Failover request. The method will close the
// http.Response Body if it receives an error.
func (client DevicesClient) FailoverSender(req *http.Request) (future DevicesFailoverFuture, err error) {
	sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client))
	var resp *http.Response
	resp, err = autorest.SendWithSender(client, req, sd...)
	if err != nil {
		return
	}
	future.Future, err = azure.NewFutureFromResponse(resp)
	return
}

// FailoverResponder handles the response to the Failover request. The method always
// closes the http.Response Body.
func (client DevicesClient) FailoverResponder(resp *http.Response) (result autorest.Response, err error) {
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent),
		autorest.ByClosing())
	result.Response = resp
	return
}

// Get returns the properties of the specified device.
// Parameters:
// deviceName - the device name
// resourceGroupName - the resource group name
// managerName - the manager name
// expand - specify $expand=details to populate additional fields related to the device or
// $expand=rolloverdetails to populate additional fields related to the service data encryption key rollover on
// device
func (client DevicesClient) Get(ctx context.Context, deviceName string, resourceGroupName string, managerName string, expand string) (result Device, err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/DevicesClient.Get")
		defer func() {
			sc := -1
			if result.Response.Response != nil {
				sc = result.Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	if err := validation.Validate([]validation.Validation{
		{TargetValue: managerName,
			Constraints: []validation.Constraint{{Target: "managerName", Name: validation.MaxLength, Rule: 50, Chain: nil},
				{Target: "managerName", Name: validation.MinLength, Rule: 2, Chain: nil}}}}); err != nil {
		return result, validation.NewError("storsimple.DevicesClient", "Get", err.Error())
	}

	req, err := client.GetPreparer(ctx, deviceName, resourceGroupName, managerName, expand)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "Get", nil, "Failure preparing request")
		return
	}

	resp, err := client.GetSender(req)
	if err != nil {
		result.Response = autorest.Response{Response: resp}
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "Get", resp, "Failure sending request")
		return
	}

	result, err = client.GetResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "Get", resp, "Failure responding to request")
	}

	return
}

// GetPreparer prepares the Get request.
func (client DevicesClient) GetPreparer(ctx context.Context, deviceName string, resourceGroupName string, managerName string, expand string) (*http.Request, error) {
	pathParameters := map[string]interface{}{
		"deviceName":        deviceName,
		"managerName":       managerName,
		"resourceGroupName": resourceGroupName,
		"subscriptionId":    client.SubscriptionID,
	}

	const APIVersion = "2017-06-01"
	queryParameters := map[string]interface{}{
		"api-version": APIVersion,
	}
	if len(expand) > 0 {
		queryParameters["$expand"] = autorest.Encode("query", expand)
	}

	preparer := autorest.CreatePreparer(
		autorest.AsGet(),
		autorest.WithBaseURL(client.BaseURI),
		autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.StorSimple/managers/{managerName}/devices/{deviceName}", pathParameters),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// GetSender sends the Get request. The method will close the
// http.Response Body if it receives an error.
func (client DevicesClient) GetSender(req *http.Request) (*http.Response, error) {
	sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client))
	return autorest.SendWithSender(client, req, sd...)
}

// GetResponder handles the response to the Get request. The method always
// closes the http.Response Body.
func (client DevicesClient) GetResponder(resp *http.Response) (result Device, err error) {
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK),
		autorest.ByUnmarshallingJSON(&result),
		autorest.ByClosing())
	result.Response = autorest.Response{Response: resp}
	return
}

// GetUpdateSummary returns the update summary of the specified device name.
// Parameters:
// deviceName - the device name
// resourceGroupName - the resource group name
// managerName - the manager name
func (client DevicesClient) GetUpdateSummary(ctx context.Context, deviceName string, resourceGroupName string, managerName string) (result Updates, err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/DevicesClient.GetUpdateSummary")
		defer func() {
			sc := -1
			if result.Response.Response != nil {
				sc = result.Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	if err := validation.Validate([]validation.Validation{
		{TargetValue: managerName,
			Constraints: []validation.Constraint{{Target: "managerName", Name: validation.MaxLength, Rule: 50, Chain: nil},
				{Target: "managerName", Name: validation.MinLength, Rule: 2, Chain: nil}}}}); err != nil {
		return result, validation.NewError("storsimple.DevicesClient", "GetUpdateSummary", err.Error())
	}

	req, err := client.GetUpdateSummaryPreparer(ctx, deviceName, resourceGroupName, managerName)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "GetUpdateSummary", nil, "Failure preparing request")
		return
	}

	resp, err := client.GetUpdateSummarySender(req)
	if err != nil {
		result.Response = autorest.Response{Response: resp}
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "GetUpdateSummary", resp, "Failure sending request")
		return
	}

	result, err = client.GetUpdateSummaryResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "GetUpdateSummary", resp, "Failure responding to request")
	}

	return
}

// GetUpdateSummaryPreparer prepares the GetUpdateSummary request.
func (client DevicesClient) GetUpdateSummaryPreparer(ctx context.Context, deviceName string, resourceGroupName string, managerName string) (*http.Request, error) {
	pathParameters := map[string]interface{}{
		"deviceName":        deviceName,
		"managerName":       managerName,
		"resourceGroupName": resourceGroupName,
		"subscriptionId":    client.SubscriptionID,
	}

	const APIVersion = "2017-06-01"
	queryParameters := map[string]interface{}{
		"api-version": APIVersion,
	}

	preparer := autorest.CreatePreparer(
		autorest.AsGet(),
		autorest.WithBaseURL(client.BaseURI),
		autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.StorSimple/managers/{managerName}/devices/{deviceName}/updateSummary/default", pathParameters),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// GetUpdateSummarySender sends the GetUpdateSummary request. The method will close the
// http.Response Body if it receives an error.
func (client DevicesClient) GetUpdateSummarySender(req *http.Request) (*http.Response, error) {
	sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client))
	return autorest.SendWithSender(client, req, sd...)
}

// GetUpdateSummaryResponder handles the response to the GetUpdateSummary request. The method always
// closes the http.Response Body.
func (client DevicesClient) GetUpdateSummaryResponder(resp *http.Response) (result Updates, err error) {
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK),
		autorest.ByUnmarshallingJSON(&result),
		autorest.ByClosing())
	result.Response = autorest.Response{Response: resp}
	return
}

// InstallUpdates downloads and installs the updates on the device.
// Parameters:
// deviceName - the device name
// resourceGroupName - the resource group name
// managerName - the manager name
func (client DevicesClient) InstallUpdates(ctx context.Context, deviceName string, resourceGroupName string, managerName string) (result DevicesInstallUpdatesFuture, err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/DevicesClient.InstallUpdates")
		defer func() {
			sc := -1
			if result.Response() != nil {
				sc = result.Response().StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	if err := validation.Validate([]validation.Validation{
		{TargetValue: managerName,
			Constraints: []validation.Constraint{{Target: "managerName", Name: validation.MaxLength, Rule: 50, Chain: nil},
				{Target: "managerName", Name: validation.MinLength, Rule: 2, Chain: nil}}}}); err != nil {
		return result, validation.NewError("storsimple.DevicesClient", "InstallUpdates", err.Error())
	}

	req, err := client.InstallUpdatesPreparer(ctx, deviceName, resourceGroupName, managerName)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "InstallUpdates", nil, "Failure preparing request")
		return
	}

	result, err = client.InstallUpdatesSender(req)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "InstallUpdates", result.Response(), "Failure sending request")
		return
	}

	return
}

// InstallUpdatesPreparer prepares the InstallUpdates request.
func (client DevicesClient) InstallUpdatesPreparer(ctx context.Context, deviceName string, resourceGroupName string, managerName string) (*http.Request, error) {
	pathParameters := map[string]interface{}{
		"deviceName":        deviceName,
		"managerName":       managerName,
		"resourceGroupName": resourceGroupName,
		"subscriptionId":    client.SubscriptionID,
	}

	const APIVersion = "2017-06-01"
	queryParameters := map[string]interface{}{
		"api-version": APIVersion,
	}

	preparer := autorest.CreatePreparer(
		autorest.AsPost(),
		autorest.WithBaseURL(client.BaseURI),
		autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.StorSimple/managers/{managerName}/devices/{deviceName}/installUpdates", pathParameters),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// InstallUpdatesSender sends the InstallUpdates request. The method will close the
// http.Response Body if it receives an error.
func (client DevicesClient) InstallUpdatesSender(req *http.Request) (future DevicesInstallUpdatesFuture, err error) {
	sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client))
	var resp *http.Response
	resp, err = autorest.SendWithSender(client, req, sd...)
	if err != nil {
		return
	}
	future.Future, err = azure.NewFutureFromResponse(resp)
	return
}

// InstallUpdatesResponder handles the response to the InstallUpdates request. The method always
// closes the http.Response Body.
func (client DevicesClient) InstallUpdatesResponder(resp *http.Response) (result autorest.Response, err error) {
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent),
		autorest.ByClosing())
	result.Response = resp
	return
}

// ListByManager returns the list of devices for the specified manager.
// Parameters:
// resourceGroupName - the resource group name
// managerName - the manager name
// expand - specify $expand=details to populate additional fields related to the device or
// $expand=rolloverdetails to populate additional fields related to the service data encryption key rollover on
// device
func (client DevicesClient) ListByManager(ctx context.Context, resourceGroupName string, managerName string, expand string) (result DeviceList, err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/DevicesClient.ListByManager")
		defer func() {
			sc := -1
			if result.Response.Response != nil {
				sc = result.Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	if err := validation.Validate([]validation.Validation{
		{TargetValue: managerName,
			Constraints: []validation.Constraint{{Target: "managerName", Name: validation.MaxLength, Rule: 50, Chain: nil},
				{Target: "managerName", Name: validation.MinLength, Rule: 2, Chain: nil}}}}); err != nil {
		return result, validation.NewError("storsimple.DevicesClient", "ListByManager", err.Error())
	}

	req, err := client.ListByManagerPreparer(ctx, resourceGroupName, managerName, expand)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "ListByManager", nil, "Failure preparing request")
		return
	}

	resp, err := client.ListByManagerSender(req)
	if err != nil {
		result.Response = autorest.Response{Response: resp}
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "ListByManager", resp, "Failure sending request")
		return
	}

	result, err = client.ListByManagerResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "ListByManager", resp, "Failure responding to request")
	}

	return
}

// ListByManagerPreparer prepares the ListByManager request.
func (client DevicesClient) ListByManagerPreparer(ctx context.Context, resourceGroupName string, managerName string, expand string) (*http.Request, error) {
	pathParameters := map[string]interface{}{
		"managerName":       managerName,
		"resourceGroupName": resourceGroupName,
		"subscriptionId":    client.SubscriptionID,
	}

	const APIVersion = "2017-06-01"
	queryParameters := map[string]interface{}{
		"api-version": APIVersion,
	}
	if len(expand) > 0 {
		queryParameters["$expand"] = autorest.Encode("query", expand)
	}

	preparer := autorest.CreatePreparer(
		autorest.AsGet(),
		autorest.WithBaseURL(client.BaseURI),
		autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.StorSimple/managers/{managerName}/devices", pathParameters),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// ListByManagerSender sends the ListByManager request. The method will close the
// http.Response Body if it receives an error.
func (client DevicesClient) ListByManagerSender(req *http.Request) (*http.Response, error) {
	sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client))
	return autorest.SendWithSender(client, req, sd...)
}

// ListByManagerResponder handles the response to the ListByManager request. The method always
// closes the http.Response Body.
func (client DevicesClient) ListByManagerResponder(resp *http.Response) (result DeviceList, err error) {
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK),
		autorest.ByUnmarshallingJSON(&result),
		autorest.ByClosing())
	result.Response = autorest.Response{Response: resp}
	return
}

// ListFailoverSets returns all failover sets for a given device and their eligibility for participating in a failover.
// A failover set refers to a set of volume containers that need to be failed-over as a single unit to maintain data
// integrity.
// Parameters:
// deviceName - the device name
// resourceGroupName - the resource group name
// managerName - the manager name
func (client DevicesClient) ListFailoverSets(ctx context.Context, deviceName string, resourceGroupName string, managerName string) (result FailoverSetsList, err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/DevicesClient.ListFailoverSets")
		defer func() {
			sc := -1
			if result.Response.Response != nil {
				sc = result.Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	if err := validation.Validate([]validation.Validation{
		{TargetValue: managerName,
			Constraints: []validation.Constraint{{Target: "managerName", Name: validation.MaxLength, Rule: 50, Chain: nil},
				{Target: "managerName", Name: validation.MinLength, Rule: 2, Chain: nil}}}}); err != nil {
		return result, validation.NewError("storsimple.DevicesClient", "ListFailoverSets", err.Error())
	}

	req, err := client.ListFailoverSetsPreparer(ctx, deviceName, resourceGroupName, managerName)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "ListFailoverSets", nil, "Failure preparing request")
		return
	}

	resp, err := client.ListFailoverSetsSender(req)
	if err != nil {
		result.Response = autorest.Response{Response: resp}
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "ListFailoverSets", resp, "Failure sending request")
		return
	}

	result, err = client.ListFailoverSetsResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "ListFailoverSets", resp, "Failure responding to request")
	}

	return
}

// ListFailoverSetsPreparer prepares the ListFailoverSets request.
func (client DevicesClient) ListFailoverSetsPreparer(ctx context.Context, deviceName string, resourceGroupName string, managerName string) (*http.Request, error) {
	pathParameters := map[string]interface{}{
		"deviceName":        deviceName,
		"managerName":       managerName,
		"resourceGroupName": resourceGroupName,
		"subscriptionId":    client.SubscriptionID,
	}

	const APIVersion = "2017-06-01"
	queryParameters := map[string]interface{}{
		"api-version": APIVersion,
	}

	preparer := autorest.CreatePreparer(
		autorest.AsPost(),
		autorest.WithBaseURL(client.BaseURI),
		autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.StorSimple/managers/{managerName}/devices/{deviceName}/listFailoverSets", pathParameters),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// ListFailoverSetsSender sends the ListFailoverSets request. The method will close the
// http.Response Body if it receives an error.
func (client DevicesClient) ListFailoverSetsSender(req *http.Request) (*http.Response, error) {
	sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client))
	return autorest.SendWithSender(client, req, sd...)
}

// ListFailoverSetsResponder handles the response to the ListFailoverSets request. The method always
// closes the http.Response Body.
func (client DevicesClient) ListFailoverSetsResponder(resp *http.Response) (result FailoverSetsList, err error) {
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK),
		autorest.ByUnmarshallingJSON(&result),
		autorest.ByClosing())
	result.Response = autorest.Response{Response: resp}
	return
}

// ListFailoverTargets given a list of volume containers to be failed over from a source device, this method returns
// the eligibility result, as a failover target, for all devices under that resource.
// Parameters:
// sourceDeviceName - the source device name on which failover is performed.
// parameters - listFailoverTargetsRequest containing the list of volume containers to be failed over.
// resourceGroupName - the resource group name
// managerName - the manager name
func (client DevicesClient) ListFailoverTargets(ctx context.Context, sourceDeviceName string, parameters ListFailoverTargetsRequest, resourceGroupName string, managerName string) (result FailoverTargetsList, err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/DevicesClient.ListFailoverTargets")
		defer func() {
			sc := -1
			if result.Response.Response != nil {
				sc = result.Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	if err := validation.Validate([]validation.Validation{
		{TargetValue: managerName,
			Constraints: []validation.Constraint{{Target: "managerName", Name: validation.MaxLength, Rule: 50, Chain: nil},
				{Target: "managerName", Name: validation.MinLength, Rule: 2, Chain: nil}}}}); err != nil {
		return result, validation.NewError("storsimple.DevicesClient", "ListFailoverTargets", err.Error())
	}

	req, err := client.ListFailoverTargetsPreparer(ctx, sourceDeviceName, parameters, resourceGroupName, managerName)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "ListFailoverTargets", nil, "Failure preparing request")
		return
	}

	resp, err := client.ListFailoverTargetsSender(req)
	if err != nil {
		result.Response = autorest.Response{Response: resp}
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "ListFailoverTargets", resp, "Failure sending request")
		return
	}

	result, err = client.ListFailoverTargetsResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "ListFailoverTargets", resp, "Failure responding to request")
	}

	return
}

// ListFailoverTargetsPreparer prepares the ListFailoverTargets request.
func (client DevicesClient) ListFailoverTargetsPreparer(ctx context.Context, sourceDeviceName string, parameters ListFailoverTargetsRequest, resourceGroupName string, managerName string) (*http.Request, error) {
	pathParameters := map[string]interface{}{
		"managerName":       managerName,
		"resourceGroupName": resourceGroupName,
		"sourceDeviceName":  sourceDeviceName,
		"subscriptionId":    client.SubscriptionID,
	}

	const APIVersion = "2017-06-01"
	queryParameters := map[string]interface{}{
		"api-version": APIVersion,
	}

	preparer := autorest.CreatePreparer(
		autorest.AsContentType("application/json; charset=utf-8"),
		autorest.AsPost(),
		autorest.WithBaseURL(client.BaseURI),
		autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.StorSimple/managers/{managerName}/devices/{sourceDeviceName}/listFailoverTargets", pathParameters),
		autorest.WithJSON(parameters),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// ListFailoverTargetsSender sends the ListFailoverTargets request. The method will close the
// http.Response Body if it receives an error.
func (client DevicesClient) ListFailoverTargetsSender(req *http.Request) (*http.Response, error) {
	sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client))
	return autorest.SendWithSender(client, req, sd...)
}

// ListFailoverTargetsResponder handles the response to the ListFailoverTargets request. The method always
// closes the http.Response Body.
func (client DevicesClient) ListFailoverTargetsResponder(resp *http.Response) (result FailoverTargetsList, err error) {
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK),
		autorest.ByUnmarshallingJSON(&result),
		autorest.ByClosing())
	result.Response = autorest.Response{Response: resp}
	return
}

// ListMetricDefinition gets the metric definitions for the specified device.
// Parameters:
// deviceName - the device name
// resourceGroupName - the resource group name
// managerName - the manager name
func (client DevicesClient) ListMetricDefinition(ctx context.Context, deviceName string, resourceGroupName string, managerName string) (result MetricDefinitionList, err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/DevicesClient.ListMetricDefinition")
		defer func() {
			sc := -1
			if result.Response.Response != nil {
				sc = result.Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	if err := validation.Validate([]validation.Validation{
		{TargetValue: managerName,
			Constraints: []validation.Constraint{{Target: "managerName", Name: validation.MaxLength, Rule: 50, Chain: nil},
				{Target: "managerName", Name: validation.MinLength, Rule: 2, Chain: nil}}}}); err != nil {
		return result, validation.NewError("storsimple.DevicesClient", "ListMetricDefinition", err.Error())
	}

	req, err := client.ListMetricDefinitionPreparer(ctx, deviceName, resourceGroupName, managerName)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "ListMetricDefinition", nil, "Failure preparing request")
		return
	}

	resp, err := client.ListMetricDefinitionSender(req)
	if err != nil {
		result.Response = autorest.Response{Response: resp}
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "ListMetricDefinition", resp, "Failure sending request")
		return
	}

	result, err = client.ListMetricDefinitionResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "ListMetricDefinition", resp, "Failure responding to request")
	}

	return
}

// ListMetricDefinitionPreparer prepares the ListMetricDefinition request.
func (client DevicesClient) ListMetricDefinitionPreparer(ctx context.Context, deviceName string, resourceGroupName string, managerName string) (*http.Request, error) {
	pathParameters := map[string]interface{}{
		"deviceName":        deviceName,
		"managerName":       managerName,
		"resourceGroupName": resourceGroupName,
		"subscriptionId":    client.SubscriptionID,
	}

	const APIVersion = "2017-06-01"
	queryParameters := map[string]interface{}{
		"api-version": APIVersion,
	}

	preparer := autorest.CreatePreparer(
		autorest.AsGet(),
		autorest.WithBaseURL(client.BaseURI),
		autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.StorSimple/managers/{managerName}/devices/{deviceName}/metricsDefinitions", pathParameters),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// ListMetricDefinitionSender sends the ListMetricDefinition request. The method will close the
// http.Response Body if it receives an error.
func (client DevicesClient) ListMetricDefinitionSender(req *http.Request) (*http.Response, error) {
	sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client))
	return autorest.SendWithSender(client, req, sd...)
}

// ListMetricDefinitionResponder handles the response to the ListMetricDefinition request. The method always
// closes the http.Response Body.
func (client DevicesClient) ListMetricDefinitionResponder(resp *http.Response) (result MetricDefinitionList, err error) {
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK),
		autorest.ByUnmarshallingJSON(&result),
		autorest.ByClosing())
	result.Response = autorest.Response{Response: resp}
	return
}

// ListMetrics gets the metrics for the specified device.
// Parameters:
// deviceName - the device name
// resourceGroupName - the resource group name
// managerName - the manager name
// filter - oData Filter options
func (client DevicesClient) ListMetrics(ctx context.Context, deviceName string, resourceGroupName string, managerName string, filter string) (result MetricList, err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/DevicesClient.ListMetrics")
		defer func() {
			sc := -1
			if result.Response.Response != nil {
				sc = result.Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	if err := validation.Validate([]validation.Validation{
		{TargetValue: managerName,
			Constraints: []validation.Constraint{{Target: "managerName", Name: validation.MaxLength, Rule: 50, Chain: nil},
				{Target: "managerName", Name: validation.MinLength, Rule: 2, Chain: nil}}}}); err != nil {
		return result, validation.NewError("storsimple.DevicesClient", "ListMetrics", err.Error())
	}

	req, err := client.ListMetricsPreparer(ctx, deviceName, resourceGroupName, managerName, filter)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "ListMetrics", nil, "Failure preparing request")
		return
	}

	resp, err := client.ListMetricsSender(req)
	if err != nil {
		result.Response = autorest.Response{Response: resp}
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "ListMetrics", resp, "Failure sending request")
		return
	}

	result, err = client.ListMetricsResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "ListMetrics", resp, "Failure responding to request")
	}

	return
}

// ListMetricsPreparer prepares the ListMetrics request.
func (client DevicesClient) ListMetricsPreparer(ctx context.Context, deviceName string, resourceGroupName string, managerName string, filter string) (*http.Request, error) {
	pathParameters := map[string]interface{}{
		"deviceName":        deviceName,
		"managerName":       managerName,
		"resourceGroupName": resourceGroupName,
		"subscriptionId":    client.SubscriptionID,
	}

	const APIVersion = "2017-06-01"
	queryParameters := map[string]interface{}{
		"$filter":     autorest.Encode("query", filter),
		"api-version": APIVersion,
	}

	preparer := autorest.CreatePreparer(
		autorest.AsGet(),
		autorest.WithBaseURL(client.BaseURI),
		autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.StorSimple/managers/{managerName}/devices/{deviceName}/metrics", pathParameters),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// ListMetricsSender sends the ListMetrics request. The method will close the
// http.Response Body if it receives an error.
func (client DevicesClient) ListMetricsSender(req *http.Request) (*http.Response, error) {
	sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client))
	return autorest.SendWithSender(client, req, sd...)
}

// ListMetricsResponder handles the response to the ListMetrics request. The method always
// closes the http.Response Body.
func (client DevicesClient) ListMetricsResponder(resp *http.Response) (result MetricList, err error) {
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK),
		autorest.ByUnmarshallingJSON(&result),
		autorest.ByClosing())
	result.Response = autorest.Response{Response: resp}
	return
}

// ScanForUpdates scans for updates on the device.
// Parameters:
// deviceName - the device name
// resourceGroupName - the resource group name
// managerName - the manager name
func (client DevicesClient) ScanForUpdates(ctx context.Context, deviceName string, resourceGroupName string, managerName string) (result DevicesScanForUpdatesFuture, err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/DevicesClient.ScanForUpdates")
		defer func() {
			sc := -1
			if result.Response() != nil {
				sc = result.Response().StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	if err := validation.Validate([]validation.Validation{
		{TargetValue: managerName,
			Constraints: []validation.Constraint{{Target: "managerName", Name: validation.MaxLength, Rule: 50, Chain: nil},
				{Target: "managerName", Name: validation.MinLength, Rule: 2, Chain: nil}}}}); err != nil {
		return result, validation.NewError("storsimple.DevicesClient", "ScanForUpdates", err.Error())
	}

	req, err := client.ScanForUpdatesPreparer(ctx, deviceName, resourceGroupName, managerName)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "ScanForUpdates", nil, "Failure preparing request")
		return
	}

	result, err = client.ScanForUpdatesSender(req)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "ScanForUpdates", result.Response(), "Failure sending request")
		return
	}

	return
}

// ScanForUpdatesPreparer prepares the ScanForUpdates request.
func (client DevicesClient) ScanForUpdatesPreparer(ctx context.Context, deviceName string, resourceGroupName string, managerName string) (*http.Request, error) {
	pathParameters := map[string]interface{}{
		"deviceName":        deviceName,
		"managerName":       managerName,
		"resourceGroupName": resourceGroupName,
		"subscriptionId":    client.SubscriptionID,
	}

	const APIVersion = "2017-06-01"
	queryParameters := map[string]interface{}{
		"api-version": APIVersion,
	}

	preparer := autorest.CreatePreparer(
		autorest.AsPost(),
		autorest.WithBaseURL(client.BaseURI),
		autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.StorSimple/managers/{managerName}/devices/{deviceName}/scanForUpdates", pathParameters),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// ScanForUpdatesSender sends the ScanForUpdates request. The method will close the
// http.Response Body if it receives an error.
func (client DevicesClient) ScanForUpdatesSender(req *http.Request) (future DevicesScanForUpdatesFuture, err error) {
	sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client))
	var resp *http.Response
	resp, err = autorest.SendWithSender(client, req, sd...)
	if err != nil {
		return
	}
	future.Future, err = azure.NewFutureFromResponse(resp)
	return
}

// ScanForUpdatesResponder handles the response to the ScanForUpdates request. The method always
// closes the http.Response Body.
func (client DevicesClient) ScanForUpdatesResponder(resp *http.Response) (result autorest.Response, err error) {
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent),
		autorest.ByClosing())
	result.Response = resp
	return
}

// Update patches the device.
// Parameters:
// deviceName - the device name
// parameters - patch representation of the device.
// resourceGroupName - the resource group name
// managerName - the manager name
func (client DevicesClient) Update(ctx context.Context, deviceName string, parameters DevicePatch, resourceGroupName string, managerName string) (result Device, err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/DevicesClient.Update")
		defer func() {
			sc := -1
			if result.Response.Response != nil {
				sc = result.Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	if err := validation.Validate([]validation.Validation{
		{TargetValue: managerName,
			Constraints: []validation.Constraint{{Target: "managerName", Name: validation.MaxLength, Rule: 50, Chain: nil},
				{Target: "managerName", Name: validation.MinLength, Rule: 2, Chain: nil}}}}); err != nil {
		return result, validation.NewError("storsimple.DevicesClient", "Update", err.Error())
	}

	req, err := client.UpdatePreparer(ctx, deviceName, parameters, resourceGroupName, managerName)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "Update", nil, "Failure preparing request")
		return
	}

	resp, err := client.UpdateSender(req)
	if err != nil {
		result.Response = autorest.Response{Response: resp}
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "Update", resp, "Failure sending request")
		return
	}

	result, err = client.UpdateResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storsimple.DevicesClient", "Update", resp, "Failure responding to request")
	}

	return
}

// UpdatePreparer prepares the Update request.
func (client DevicesClient) UpdatePreparer(ctx context.Context, deviceName string, parameters DevicePatch, resourceGroupName string, managerName string) (*http.Request, error) {
	pathParameters := map[string]interface{}{
		"deviceName":        deviceName,
		"managerName":       managerName,
		"resourceGroupName": resourceGroupName,
		"subscriptionId":    client.SubscriptionID,
	}

	const APIVersion = "2017-06-01"
	queryParameters := map[string]interface{}{
		"api-version": APIVersion,
	}

	preparer := autorest.CreatePreparer(
		autorest.AsContentType("application/json; charset=utf-8"),
		autorest.AsPatch(),
		autorest.WithBaseURL(client.BaseURI),
		autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.StorSimple/managers/{managerName}/devices/{deviceName}", pathParameters),
		autorest.WithJSON(parameters),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// UpdateSender sends the Update request. The method will close the
// http.Response Body if it receives an error.
func (client DevicesClient) UpdateSender(req *http.Request) (*http.Response, error) {
	sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client))
	return autorest.SendWithSender(client, req, sd...)
}

// UpdateResponder handles the response to the Update request. The method always
// closes the http.Response Body.
func (client DevicesClient) UpdateResponder(resp *http.Response) (result Device, err error) {
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK),
		autorest.ByUnmarshallingJSON(&result),
		autorest.ByClosing())
	result.Response = autorest.Response{Response: resp}
	return
}