text:
package testing

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"sync"
	"testing"
	"time"

	"k8s.io/apimachinery/pkg/util/sets"
	"k8s.io/utils/exec"
	testingexec "k8s.io/utils/exec/testing"
	utilstrings "k8s.io/utils/strings"

	v1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/resource"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/types"
	"k8s.io/apimachinery/pkg/util/uuid"
	utiltesting "k8s.io/client-go/util/testing"
	"k8s.io/kubernetes/pkg/volume"
	. "k8s.io/kubernetes/pkg/volume"
	"k8s.io/kubernetes/pkg/volume/util"
	"k8s.io/kubernetes/pkg/volume/util/recyclerclient"
	volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
	"k8s.io/kubernetes/pkg/volume/util/volumepathhandler"
)

const (
	// A hook specified in storage class to indicate it's provisioning
	// is expected to fail.
	ExpectProvisionFailureKey = "expect-provision-failure"
	// The node is marked as uncertain. The attach operation will fail and return timeout error
	// for the first attach call. The following call will return sucesssfully.
	UncertainAttachNode = "uncertain-attach-node"
	// The node is marked as timeout. The attach operation will always fail and return timeout error
	// but the operation is actually succeeded.
	TimeoutAttachNode = "timeout-attach-node"
	// The node is marked as multi-attach which means it is allowed to attach the volume to multiple nodes.
	MultiAttachNode = "multi-attach-node"
	// TimeoutOnSetupVolumeName will cause Setup call to timeout but volume will finish mounting.
	TimeoutOnSetupVolumeName = "timeout-setup-volume"
	// FailOnSetupVolumeName will cause setup call to fail
	FailOnSetupVolumeName = "fail-setup-volume"
	//TimeoutAndFailOnSetupVolumeName will first timeout and then fail the setup
	TimeoutAndFailOnSetupVolumeName = "timeout-and-fail-setup-volume"
	// SuccessAndTimeoutSetupVolumeName will cause first mount operation to succeed but subsequent attempts to timeout
	SuccessAndTimeoutSetupVolumeName = "success-and-timeout-setup-volume-name"
	// SuccessAndFailOnSetupVolumeName will cause first mount operation to succeed but subsequent attempts to fail
	SuccessAndFailOnSetupVolumeName = "success-and-failed-setup-device-name"

	// TimeoutOnMountDeviceVolumeName will cause MountDevice call to timeout but Setup will finish.
	TimeoutOnMountDeviceVolumeName = "timeout-mount-device-volume"
	// TimeoutAndFailOnMountDeviceVolumeName will cause first MountDevice call to timeout but second call will fail
	TimeoutAndFailOnMountDeviceVolumeName = "timeout-and-fail-mount-device-name"
	// FailMountDeviceVolumeName will cause MountDevice operation on volume to fail
	FailMountDeviceVolumeName = "fail-mount-device-volume-name"
	// SuccessAndTimeoutDeviceName will cause first mount operation to succeed but subsequent attempts to timeout
	SuccessAndTimeoutDeviceName = "success-and-timeout-device-name"
	// SuccessAndFailOnMountDeviceName will cause first mount operation to succeed but subsequent attempts to fail
	SuccessAndFailOnMountDeviceName = "success-and-failed-mount-device-name"

	// FailWithInUseVolumeName will cause NodeExpandVolume to result in FailedPrecondition error
	FailWithInUseVolumeName = "fail-expansion-in-use"

	FailVolumeExpansion = "fail-expansion-test"

	deviceNotMounted     = "deviceNotMounted"
	deviceMountUncertain = "deviceMountUncertain"
	deviceMounted        = "deviceMounted"

	volumeNotMounted     = "volumeNotMounted"
	volumeMountUncertain = "volumeMountUncertain"
	volumeMounted        = "volumeMounted"
)

// CommandScript is used to pre-configure a command that will be executed and
// optionally set it's output (stdout and stderr combined) and return code.
type CommandScript struct {
	// Cmd is the command to execute, e.g. "ls"
	Cmd string
	// Args is a slice of arguments to pass to the command, e.g. "-a"
	Args []string
	// Output is the combined stdout and stderr of the command to return
	Output string
	// ReturnCode is the exit code for the command. Setting this to non-zero will
	// cause the command to return an error with this exit code set.
	ReturnCode int
}

// ScriptCommands configures fe, the FakeExec, to have a pre-configured list of
// commands to expect. Calling more commands using fe than those scripted will
// result in a panic. By default, the fe does not enforce command argument checking
// or order -- if you have given an Output to the command, the first command scripted
// will return its output on the first command call, even if the command called is
// different than the one scripted. This is mostly useful to make sure that the
// right number of commands were called. If you want to check the exact commands
// and arguments were called, set fe.ExectOrder to true.
func ScriptCommands(fe *testingexec.FakeExec, scripts []CommandScript) {
	fe.DisableScripts = false
	for _, script := range scripts {
		fakeCmd := &testingexec.FakeCmd{}
		cmdAction := makeFakeCmd(fakeCmd, script.Cmd, script.Args...)
		outputAction := makeFakeOutput(script.Output, script.ReturnCode)
		fakeCmd.CombinedOutputScript = append(fakeCmd.CombinedOutputScript, outputAction)
		fe.CommandScript = append(fe.CommandScript, cmdAction)
	}
}

func makeFakeCmd(fakeCmd *testingexec.FakeCmd, cmd string, args ...string) testingexec.FakeCommandAction {
	fc := fakeCmd
	c := cmd
	a := args
	return func(cmd string, args ...string) exec.Cmd {
		command := testingexec.InitFakeCmd(fc, c, a...)
		return command
	}
}

func makeFakeOutput(output string, rc int) testingexec.FakeAction {
	o := output
	var e error
	if rc != 0 {
		e = testingexec.FakeExitError{Status: rc}
	}
	return func() ([]byte, []byte, error) {
		return []byte(o), nil, e
	}
}

func ProbeVolumePlugins(config VolumeConfig) []VolumePlugin {
	if _, ok := config.OtherAttributes["fake-property"]; ok {
		return []VolumePlugin{
			&FakeVolumePlugin{
				PluginName: "fake-plugin",
				Host:       nil,
				// SomeFakeProperty: config.OtherAttributes["fake-property"] -- string, may require parsing by plugin
			},
		}
	}
	return []VolumePlugin{&FakeVolumePlugin{PluginName: "fake-plugin"}}
}

// FakeVolumePlugin is useful for testing.  It tries to be a fully compliant
// plugin, but all it does is make empty directories.
// Use as:
//   volume.RegisterPlugin(&FakePlugin{"fake-name"})
type FakeVolumePlugin struct {
	sync.RWMutex
	PluginName             string
	Host                   VolumeHost
	Config                 VolumeConfig
	LastProvisionerOptions VolumeOptions
	NewAttacherCallCount   int
	NewDetacherCallCount   int
	VolumeLimits           map[string]int64
	VolumeLimitsError      error
	LimitKey               string
	ProvisionDelaySeconds  int
	SupportsRemount        bool

	// default to false which means it is attachable by default
	NonAttachable bool

	// Add callbacks as needed
	WaitForAttachHook func(spec *Spec, devicePath string, pod *v1.Pod, spectimeout time.Duration) (string, error)
	UnmountDeviceHook func(globalMountPath string) error

	Mounters             []*FakeVolume
	Unmounters           []*FakeVolume
	Attachers            []*FakeVolume
	Detachers            []*FakeVolume
	BlockVolumeMappers   []*FakeVolume
	BlockVolumeUnmappers []*FakeVolume
}

var _ VolumePlugin = &FakeVolumePlugin{}
var _ BlockVolumePlugin = &FakeVolumePlugin{}
var _ RecyclableVolumePlugin = &FakeVolumePlugin{}
var _ DeletableVolumePlugin = &FakeVolumePlugin{}
var _ ProvisionableVolumePlugin = &FakeVolumePlugin{}
var _ AttachableVolumePlugin = &FakeVolumePlugin{}
var _ VolumePluginWithAttachLimits = &FakeVolumePlugin{}
var _ DeviceMountableVolumePlugin = &FakeVolumePlugin{}
var _ NodeExpandableVolumePlugin = &FakeVolumePlugin{}

func (plugin *FakeVolumePlugin) getFakeVolume(list *[]*FakeVolume) *FakeVolume {
	if list != nil {
		volumeList := *list
		if len(volumeList) > 0 {
			volume := volumeList[0]
			volume.Lock()
			defer volume.Unlock()
			volume.WaitForAttachHook = plugin.WaitForAttachHook
			volume.UnmountDeviceHook = plugin.UnmountDeviceHook
			return volume
		}
	}
	volume := &FakeVolume{
		WaitForAttachHook: plugin.WaitForAttachHook,
		UnmountDeviceHook: plugin.UnmountDeviceHook,
	}
	volume.VolumesAttached = make(map[string]sets.String)
	volume.DeviceMountState = make(map[string]string)
	volume.VolumeMountState = make(map[string]string)
	if list != nil {
		*list = append(*list, volume)
	}
	return volume
}

func (plugin *FakeVolumePlugin) Init(host VolumeHost) error {
	plugin.Lock()
	defer plugin.Unlock()
	plugin.Host = host
	return nil
}

func (plugin *FakeVolumePlugin) GetPluginName() string {
	plugin.RLock()
	defer plugin.RUnlock()
	return plugin.PluginName
}

func (plugin *FakeVolumePlugin) GetVolumeName(spec *Spec) (string, error) {
	var volumeName string
	if spec.Volume != nil && spec.Volume.GCEPersistentDisk != nil {
		volumeName = spec.Volume.GCEPersistentDisk.PDName
	} else if spec.PersistentVolume != nil &&
		spec.PersistentVolume.Spec.GCEPersistentDisk != nil {
		volumeName = spec.PersistentVolume.Spec.GCEPersistentDisk.PDName
	} else if spec.Volume != nil && spec.Volume.CSI != nil {
		volumeName = spec.Volume.CSI.Driver
	}
	if volumeName == "" {
		volumeName = spec.Name()
	}
	return volumeName, nil
}

func (plugin *FakeVolumePlugin) CanSupport(spec *Spec) bool {
	// TODO: maybe pattern-match on spec.Name() to decide?
	return true
}

func (plugin *FakeVolumePlugin) RequiresRemount(spec *volume.Spec) bool {
	return plugin.SupportsRemount
}

func (plugin *FakeVolumePlugin) SupportsMountOption() bool {
	return true
}

func (plugin *FakeVolumePlugin) SupportsBulkVolumeVerification() bool {
	return false
}

func (plugin *FakeVolumePlugin) NewMounter(spec *Spec, pod *v1.Pod, opts VolumeOptions) (Mounter, error) {
	plugin.Lock()
	defer plugin.Unlock()
	volume := plugin.getFakeVolume(&plugin.Mounters)
	volume.Lock()
	defer volume.Unlock()
	volume.PodUID = pod.UID
	volume.VolName = spec.Name()
	volume.Plugin = plugin
	volume.MetricsNil = MetricsNil{}
	return volume, nil
}

func (plugin *FakeVolumePlugin) GetMounters() (Mounters []*FakeVolume) {
	plugin.RLock()
	defer plugin.RUnlock()
	return plugin.Mounters
}

func (plugin *FakeVolumePlugin) NewUnmounter(volName string, podUID types.UID) (Unmounter, error) {
	plugin.Lock()
	defer plugin.Unlock()
	volume := plugin.getFakeVolume(&plugin.Unmounters)
	volume.Lock()
	defer volume.Unlock()
	volume.PodUID = podUID
	volume.VolName = volName
	volume.Plugin = plugin
	volume.MetricsNil = MetricsNil{}
	return volume, nil
}

func (plugin *FakeVolumePlugin) GetUnmounters() (Unmounters []*FakeVolume) {
	plugin.RLock()
	defer plugin.RUnlock()
	return plugin.Unmounters
}

// Block volume support
func (plugin *FakeVolumePlugin) NewBlockVolumeMapper(spec *Spec, pod *v1.Pod, opts VolumeOptions) (BlockVolumeMapper, error) {
	plugin.Lock()
	defer plugin.Unlock()
	volume := plugin.getFakeVolume(&plugin.BlockVolumeMappers)
	volume.Lock()
	defer volume.Unlock()
	if pod != nil {
		volume.PodUID = pod.UID
	}
	volume.VolName = spec.Name()
	volume.Plugin = plugin
	return volume, nil
}

// Block volume support
func (plugin *FakeVolumePlugin) GetBlockVolumeMapper() (BlockVolumeMappers []*FakeVolume) {
	plugin.RLock()
	defer plugin.RUnlock()
	return plugin.BlockVolumeMappers
}

// Block volume support
func (plugin *FakeVolumePlugin) NewBlockVolumeUnmapper(volName string, podUID types.UID) (BlockVolumeUnmapper, error) {
	plugin.Lock()
	defer plugin.Unlock()
	volume := plugin.getFakeVolume(&plugin.BlockVolumeUnmappers)
	volume.Lock()
	defer volume.Unlock()
	volume.PodUID = podUID
	volume.VolName = volName
	volume.Plugin = plugin
	return volume, nil
}

// Block volume support
func (plugin *FakeVolumePlugin) GetBlockVolumeUnmapper() (BlockVolumeUnmappers []*FakeVolume) {
	plugin.RLock()
	defer plugin.RUnlock()
	return plugin.BlockVolumeUnmappers
}

func (plugin *FakeVolumePlugin) NewAttacher() (Attacher, error) {
	plugin.Lock()
	defer plugin.Unlock()
	plugin.NewAttacherCallCount = plugin.NewAttacherCallCount + 1
	return plugin.getFakeVolume(&plugin.Attachers), nil
}

func (plugin *FakeVolumePlugin) NewDeviceMounter() (DeviceMounter, error) {
	return plugin.NewAttacher()
}

func (plugin *FakeVolumePlugin) GetAttachers() (Attachers []*FakeVolume) {
	plugin.RLock()
	defer plugin.RUnlock()
	return plugin.Attachers
}

func (plugin *FakeVolumePlugin) GetNewAttacherCallCount() int {
	plugin.RLock()
	defer plugin.RUnlock()
	return plugin.NewAttacherCallCount
}

func (plugin *FakeVolumePlugin) NewDetacher() (Detacher, error) {
	plugin.Lock()
	defer plugin.Unlock()
	plugin.NewDetacherCallCount = plugin.NewDetacherCallCount + 1
	detacher := plugin.getFakeVolume(&plugin.Detachers)
	attacherList := plugin.Attachers
	if len(attacherList) > 0 {
		detacherList := plugin.Detachers
		if len(detacherList) > 0 {
			detacherList[0].VolumesAttached = attacherList[0].VolumesAttached
		}

	}
	return detacher, nil
}

func (plugin *FakeVolumePlugin) NewDeviceUnmounter() (DeviceUnmounter, error) {
	return plugin.NewDetacher()
}

func (plugin *FakeVolumePlugin) GetDetachers() (Detachers []*FakeVolume) {
	plugin.RLock()
	defer plugin.RUnlock()
	return plugin.Detachers
}

func (plugin *FakeVolumePlugin) GetNewDetacherCallCount() int {
	plugin.RLock()
	defer plugin.RUnlock()
	return plugin.NewDetacherCallCount
}

func (plugin *FakeVolumePlugin) CanAttach(spec *Spec) (bool, error) {
	return !plugin.NonAttachable, nil
}

func (plugin *FakeVolumePlugin) CanDeviceMount(spec *Spec) (bool, error) {
	return true, nil
}

func (plugin *FakeVolumePlugin) Recycle(pvName string, spec *Spec, eventRecorder recyclerclient.RecycleEventRecorder) error {
	return nil
}

func (plugin *FakeVolumePlugin) NewDeleter(spec *Spec) (Deleter, error) {
	return &FakeDeleter{"/attributesTransferredFromSpec", MetricsNil{}}, nil
}

func (plugin *FakeVolumePlugin) NewProvisioner(options VolumeOptions) (Provisioner, error) {
	plugin.Lock()
	defer plugin.Unlock()
	plugin.LastProvisionerOptions = options
	return &FakeProvisioner{options, plugin.Host, plugin.ProvisionDelaySeconds}, nil
}

func (plugin *FakeVolumePlugin) GetAccessModes() []v1.PersistentVolumeAccessMode {
	return []v1.PersistentVolumeAccessMode{}
}

func (plugin *FakeVolumePlugin) ConstructVolumeSpec(volumeName, mountPath string) (*Spec, error) {
	return &Spec{
		Volume: &v1.Volume{
			Name: volumeName,
		},
	}, nil
}

// Block volume support
func (plugin *FakeVolumePlugin) ConstructBlockVolumeSpec(podUID types.UID, volumeName, mountPath string) (*Spec, error) {
	return &Spec{
		Volume: &v1.Volume{
			Name: volumeName,
		},
	}, nil
}

func (plugin *FakeVolumePlugin) GetDeviceMountRefs(deviceMountPath string) ([]string, error) {
	return []string{}, nil
}

// Expandable volume support
func (plugin *FakeVolumePlugin) ExpandVolumeDevice(spec *Spec, newSize resource.Quantity, oldSize resource.Quantity) (resource.Quantity, error) {
	return resource.Quantity{}, nil
}

func (plugin *FakeVolumePlugin) RequiresFSResize() bool {
	return true
}

func (plugin *FakeVolumePlugin) NodeExpand(resizeOptions NodeResizeOptions) (bool, error) {
	if resizeOptions.VolumeSpec.Name() == FailWithInUseVolumeName {
		return false, volumetypes.NewFailedPreconditionError("volume-in-use")
	}
	// Set up fakeVolumePlugin not support STAGE_UNSTAGE for testing the behavior
	// so as volume can be node published before we can resize
	if resizeOptions.CSIVolumePhase == volume.CSIVolumeStaged {
		return false, nil
	}
	if resizeOptions.CSIVolumePhase == volume.CSIVolumePublished && resizeOptions.VolumeSpec.Name() == FailVolumeExpansion {
		return false, fmt.Errorf("fail volume expansion for volume: %s", FailVolumeExpansion)
	}
	return true, nil
}

func (plugin *FakeVolumePlugin) GetVolumeLimits() (map[string]int64, error) {
	return plugin.VolumeLimits, plugin.VolumeLimitsError
}

func (plugin *FakeVolumePlugin) VolumeLimitKey(spec *Spec) string {
	return plugin.LimitKey
}

// FakeBasicVolumePlugin implements a basic volume plugin. It wrappers on
// FakeVolumePlugin but implements VolumePlugin interface only.
// It is useful to test logic involving plugin interfaces.
type FakeBasicVolumePlugin struct {
	Plugin FakeVolumePlugin
}

func (f *FakeBasicVolumePlugin) GetPluginName() string {
	return f.Plugin.GetPluginName()
}

func (f *FakeBasicVolumePlugin) GetVolumeName(spec *Spec) (string, error) {
	return f.Plugin.GetVolumeName(spec)
}

// CanSupport tests whether the plugin supports a given volume specification by
// testing volume spec name begins with plugin name or not.
// This is useful to choose plugin by volume in testing.
func (f *FakeBasicVolumePlugin) CanSupport(spec *Spec) bool {
	return strings.HasPrefix(spec.Name(), f.GetPluginName())
}

func (f *FakeBasicVolumePlugin) ConstructVolumeSpec(ame, mountPath string) (*Spec, error) {
	return f.Plugin.ConstructVolumeSpec(ame, mountPath)
}

func (f *FakeBasicVolumePlugin) Init(ost VolumeHost) error {
	return f.Plugin.Init(ost)
}

func (f *FakeBasicVolumePlugin) NewMounter(spec *Spec, pod *v1.Pod, opts VolumeOptions) (Mounter, error) {
	return f.Plugin.NewMounter(spec, pod, opts)
}

func (f *FakeBasicVolumePlugin) NewUnmounter(volName string, podUID types.UID) (Unmounter, error) {
	return f.Plugin.NewUnmounter(volName, podUID)
}

func (f *FakeBasicVolumePlugin) RequiresRemount(spec *volume.Spec) bool {
	return f.Plugin.RequiresRemount(spec)
}

func (f *FakeBasicVolumePlugin) SupportsBulkVolumeVerification() bool {
	return f.Plugin.SupportsBulkVolumeVerification()
}

func (f *FakeBasicVolumePlugin) SupportsMountOption() bool {
	return f.Plugin.SupportsMountOption()
}

var _ VolumePlugin = &FakeBasicVolumePlugin{}

// FakeDeviceMountableVolumePlugin implements an device mountable plugin based on FakeBasicVolumePlugin.
type FakeDeviceMountableVolumePlugin struct {
	FakeBasicVolumePlugin
}

func (f *FakeDeviceMountableVolumePlugin) CanDeviceMount(spec *Spec) (bool, error) {
	return true, nil
}

func (f *FakeDeviceMountableVolumePlugin) NewDeviceMounter() (DeviceMounter, error) {
	return f.Plugin.NewDeviceMounter()
}

func (f *FakeDeviceMountableVolumePlugin) NewDeviceUnmounter() (DeviceUnmounter, error) {
	return f.Plugin.NewDeviceUnmounter()
}

func (f *FakeDeviceMountableVolumePlugin) GetDeviceMountRefs(deviceMountPath string) ([]string, error) {
	return f.Plugin.GetDeviceMountRefs(deviceMountPath)
}

var _ VolumePlugin = &FakeDeviceMountableVolumePlugin{}
var _ DeviceMountableVolumePlugin = &FakeDeviceMountableVolumePlugin{}

// FakeAttachableVolumePlugin implements an attachable plugin based on FakeDeviceMountableVolumePlugin.
type FakeAttachableVolumePlugin struct {
	FakeDeviceMountableVolumePlugin
}

func (f *FakeAttachableVolumePlugin) NewAttacher() (Attacher, error) {
	return f.Plugin.NewAttacher()
}

func (f *FakeAttachableVolumePlugin) NewDetacher() (Detacher, error) {
	return f.Plugin.NewDetacher()
}

func (f *FakeAttachableVolumePlugin) CanAttach(spec *Spec) (bool, error) {
	return true, nil
}

var _ VolumePlugin = &FakeAttachableVolumePlugin{}
var _ AttachableVolumePlugin = &FakeAttachableVolumePlugin{}

type FakeFileVolumePlugin struct {
}

func (plugin *FakeFileVolumePlugin) Init(host VolumeHost) error {
	return nil
}

func (plugin *FakeFileVolumePlugin) GetPluginName() string {
	return "fake-file-plugin"
}

func (plugin *FakeFileVolumePlugin) GetVolumeName(spec *Spec) (string, error) {
	return "", nil
}

func (plugin *FakeFileVolumePlugin) CanSupport(spec *Spec) bool {
	return true
}

func (plugin *FakeFileVolumePlugin) RequiresRemount(spec *volume.Spec) bool {
	return false
}

func (plugin *FakeFileVolumePlugin) SupportsMountOption() bool {
	return false
}

func (plugin *FakeFileVolumePlugin) SupportsBulkVolumeVerification() bool {
	return false
}

func (plugin *FakeFileVolumePlugin) NewMounter(spec *Spec, podRef *v1.Pod, opts VolumeOptions) (Mounter, error) {
	return nil, nil
}

func (plugin *FakeFileVolumePlugin) NewUnmounter(name string, podUID types.UID) (Unmounter, error) {
	return nil, nil
}

func (plugin *FakeFileVolumePlugin) ConstructVolumeSpec(volumeName, mountPath string) (*Spec, error) {
	return nil, nil
}

func NewFakeFileVolumePlugin() []VolumePlugin {
	return []VolumePlugin{&FakeFileVolumePlugin{}}
}

type FakeVolume struct {
	sync.RWMutex
	PodUID  types.UID
	VolName string
	Plugin  *FakeVolumePlugin
	MetricsNil
	VolumesAttached  map[string]sets.String
	DeviceMountState map[string]string
	VolumeMountState map[string]string

	// Add callbacks as needed
	WaitForAttachHook func(spec *Spec, devicePath string, pod *v1.Pod, spectimeout time.Duration) (string, error)
	UnmountDeviceHook func(globalMountPath string) error

	SetUpCallCount              int
	TearDownCallCount           int
	AttachCallCount             int
	DetachCallCount             int
	WaitForAttachCallCount      int
	MountDeviceCallCount        int
	UnmountDeviceCallCount      int
	GetDeviceMountPathCallCount int
	SetUpDeviceCallCount        int
	TearDownDeviceCallCount     int
	MapPodDeviceCallCount       int
	UnmapPodDeviceCallCount     int
	GlobalMapPathCallCount      int
	PodDeviceMapPathCallCount   int
}

func getUniqueVolumeName(spec *Spec) (string, error) {
	var volumeName string
	if spec.Volume != nil && spec.Volume.GCEPersistentDisk != nil {
		volumeName = spec.Volume.GCEPersistentDisk.PDName
	} else if spec.PersistentVolume != nil &&
		spec.PersistentVolume.Spec.GCEPersistentDisk != nil {
		volumeName = spec.PersistentVolume.Spec.GCEPersistentDisk.PDName
	}
	if volumeName == "" {
		volumeName = spec.Name()
	}
	return volumeName, nil
}

func (_ *FakeVolume) GetAttributes() Attributes {
	return Attributes{
		ReadOnly:        false,
		Managed:         true,
		SupportsSELinux: true,
	}
}

func (fv *FakeVolume) CanMount() error {
	return nil
}

func (fv *FakeVolume) SetUp(mounterArgs MounterArgs) error {
	fv.Lock()
	defer fv.Unlock()
	err := fv.setupInternal(mounterArgs)
	fv.SetUpCallCount++
	return err
}

func (fv *FakeVolume) setupInternal(mounterArgs MounterArgs) error {
	if fv.VolName == TimeoutOnSetupVolumeName {
		fv.VolumeMountState[fv.VolName] = volumeMountUncertain
		return volumetypes.NewUncertainProgressError("time out on setup")
	}

	if fv.VolName == FailOnSetupVolumeName {
		fv.VolumeMountState[fv.VolName] = volumeNotMounted
		return fmt.Errorf("mounting volume failed")
	}

	if fv.VolName == TimeoutAndFailOnSetupVolumeName {
		_, ok := fv.VolumeMountState[fv.VolName]
		if !ok {
			fv.VolumeMountState[fv.VolName] = volumeMountUncertain
			return volumetypes.NewUncertainProgressError("time out on setup")
		}
		fv.VolumeMountState[fv.VolName] = volumeNotMounted
		return fmt.Errorf("mounting volume failed")

	}

	if fv.VolName == SuccessAndFailOnSetupVolumeName {
		_, ok := fv.VolumeMountState[fv.VolName]
		if ok {
			fv.VolumeMountState[fv.VolName] = volumeNotMounted
			return fmt.Errorf("mounting volume failed")
		}
	}

	if fv.VolName == SuccessAndTimeoutSetupVolumeName {
		_, ok := fv.VolumeMountState[fv.VolName]
		if ok {
			fv.VolumeMountState[fv.VolName] = volumeMountUncertain
			return volumetypes.NewUncertainProgressError("time out on setup")
		}
	}

	fv.VolumeMountState[fv.VolName] = volumeNotMounted
	return fv.SetUpAt(fv.getPath(), mounterArgs)
}

func (fv *FakeVolume) GetSetUpCallCount() int {
	fv.RLock()
	defer fv.RUnlock()
	return fv.SetUpCallCount
}

func (fv *FakeVolume) SetUpAt(dir string, mounterArgs MounterArgs) error {
	return os.MkdirAll(dir, 0750)
}

func (fv *FakeVolume) GetPath() string {
	fv.RLock()
	defer fv.RUnlock()
	return fv.getPath()
}

func (fv *FakeVolume) getPath() string {
	return filepath.Join(fv.Plugin.Host.GetPodVolumeDir(fv.PodUID, utilstrings.EscapeQualifiedName(fv.Plugin.PluginName), fv.VolName))
}

func (fv *FakeVolume) TearDown() error {
	fv.Lock()
	defer fv.Unlock()
	fv.TearDownCallCount++
	return fv.TearDownAt(fv.getPath())
}

func (fv *FakeVolume) GetTearDownCallCount() int {
	fv.RLock()
	defer fv.RUnlock()
	return fv.TearDownCallCount
}

func (fv *FakeVolume) TearDownAt(dir string) error {
	return os.RemoveAll(dir)
}

// Block volume support
func (fv *FakeVolume) SetUpDevice() (string, error) {
	fv.Lock()
	defer fv.Unlock()
	if fv.VolName == TimeoutOnMountDeviceVolumeName {
		fv.DeviceMountState[fv.VolName] = deviceMountUncertain
		return "", volumetypes.NewUncertainProgressError("mount failed")
	}
	if fv.VolName == FailMountDeviceVolumeName {
		fv.DeviceMountState[fv.VolName] = deviceNotMounted
		return "", fmt.Errorf("error mapping disk: %s", fv.VolName)
	}

	if fv.VolName == TimeoutAndFailOnMountDeviceVolumeName {
		_, ok := fv.DeviceMountState[fv.VolName]
		if !ok {
			fv.DeviceMountState[fv.VolName] = deviceMountUncertain
			return "", volumetypes.NewUncertainProgressError("timed out mounting error")
		}
		fv.DeviceMountState[fv.VolName] = deviceNotMounted
		return "", fmt.Errorf("error mapping disk: %s", fv.VolName)
	}

	if fv.VolName == SuccessAndTimeoutDeviceName {
		_, ok := fv.DeviceMountState[fv.VolName]
		if ok {
			fv.DeviceMountState[fv.VolName] = deviceMountUncertain
			return "", volumetypes.NewUncertainProgressError("error mounting state")
		}
	}
	if fv.VolName == SuccessAndFailOnMountDeviceName {
		_, ok := fv.DeviceMountState[fv.VolName]
		if ok {
			return "", fmt.Errorf("error mapping disk: %s", fv.VolName)
		}
	}

	fv.DeviceMountState[fv.VolName] = deviceMounted
	fv.SetUpDeviceCallCount++

	return "", nil
}

func (fv *FakeVolume) GetStagingPath() string {
	return filepath.Join(fv.Plugin.Host.GetVolumeDevicePluginDir(utilstrings.EscapeQualifiedName(fv.Plugin.PluginName)), "staging", fv.VolName)
}

// Block volume support
func (fv *FakeVolume) GetSetUpDeviceCallCount() int {
	fv.RLock()
	defer fv.RUnlock()
	return fv.SetUpDeviceCallCount
}

// Block volume support
func (fv *FakeVolume) GetGlobalMapPath(spec *Spec) (string, error) {
	fv.RLock()
	defer fv.RUnlock()
	fv.GlobalMapPathCallCount++
	return fv.getGlobalMapPath()
}

// Block volume support
func (fv *FakeVolume) getGlobalMapPath() (string, error) {
	return filepath.Join(fv.Plugin.Host.GetVolumeDevicePluginDir(utilstrings.EscapeQualifiedName(fv.Plugin.PluginName)), "pluginDependentPath"), nil
}

// Block volume support
func (fv *FakeVolume) GetGlobalMapPathCallCount() int {
	fv.RLock()
	defer fv.RUnlock()
	return fv.GlobalMapPathCallCount
}

// Block volume support
func (fv *FakeVolume) GetPodDeviceMapPath() (string, string) {
	fv.RLock()
	defer fv.RUnlock()
	fv.PodDeviceMapPathCallCount++
	return fv.getPodDeviceMapPath()
}

// Block volume support
func (fv *FakeVolume) getPodDeviceMapPath() (string, string) {
	return filepath.Join(fv.Plugin.Host.GetPodVolumeDeviceDir(fv.PodUID, utilstrings.EscapeQualifiedName(fv.Plugin.PluginName))), fv.VolName
}

// Block volume support
func (fv *FakeVolume) GetPodDeviceMapPathCallCount() int {
	fv.RLock()
	defer fv.RUnlock()
	return fv.PodDeviceMapPathCallCount
}

// Block volume support
func (fv *FakeVolume) TearDownDevice(mapPath string, devicePath string) error {
	fv.Lock()
	defer fv.Unlock()
	fv.TearDownDeviceCallCount++
	return nil
}

// Block volume support
func (fv *FakeVolume) GetTearDownDeviceCallCount() int {
	fv.RLock()
	defer fv.RUnlock()
	return fv.TearDownDeviceCallCount
}

// Block volume support
func (fv *FakeVolume) UnmapPodDevice() error {
	fv.Lock()
	defer fv.Unlock()
	fv.UnmapPodDeviceCallCount++
	return nil
}

// Block volume support
func (fv *FakeVolume) GetUnmapPodDeviceCallCount() int {
	fv.RLock()
	defer fv.RUnlock()
	return fv.UnmapPodDeviceCallCount
}

// Block volume support
func (fv *FakeVolume) MapPodDevice() (string, error) {
	fv.Lock()
	defer fv.Unlock()

	if fv.VolName == TimeoutOnSetupVolumeName {
		fv.VolumeMountState[fv.VolName] = volumeMountUncertain
		return "", volumetypes.NewUncertainProgressError("time out on setup")
	}

	if fv.VolName == FailOnSetupVolumeName {
		fv.VolumeMountState[fv.VolName] = volumeNotMounted
		return "", fmt.Errorf("mounting volume failed")
	}

	if fv.VolName == TimeoutAndFailOnSetupVolumeName {
		_, ok := fv.VolumeMountState[fv.VolName]
		if !ok {
			fv.VolumeMountState[fv.VolName] = volumeMountUncertain
			return "", volumetypes.NewUncertainProgressError("time out on setup")
		}
		fv.VolumeMountState[fv.VolName] = volumeNotMounted
		return "", fmt.Errorf("mounting volume failed")

	}

	if fv.VolName == SuccessAndFailOnSetupVolumeName {
		_, ok := fv.VolumeMountState[fv.VolName]
		if ok {
			fv.VolumeMountState[fv.VolName] = volumeNotMounted
			return "", fmt.Errorf("mounting volume failed")
		}
	}

	if fv.VolName == SuccessAndTimeoutSetupVolumeName {
		_, ok := fv.VolumeMountState[fv.VolName]
		if ok {
			fv.VolumeMountState[fv.VolName] = volumeMountUncertain
			return "", volumetypes.NewUncertainProgressError("time out on setup")
		}
	}

	fv.VolumeMountState[fv.VolName] = volumeMounted
	fv.MapPodDeviceCallCount++
	return "", nil
}

// Block volume support
func (fv *FakeVolume) GetMapPodDeviceCallCount() int {
	fv.RLock()
	defer fv.RUnlock()
	return fv.MapPodDeviceCallCount
}

func (fv *FakeVolume) Attach(spec *Spec, nodeName types.NodeName) (string, error) {
	fv.Lock()
	defer fv.Unlock()
	fv.AttachCallCount++

	volumeName, err := getUniqueVolumeName(spec)
	if err != nil {
		return "", err
	}
	volumeNodes, exist := fv.VolumesAttached[volumeName]
	if exist {
		if nodeName == UncertainAttachNode {
			return "/dev/vdb-test", nil
		}
		// even if volume was previously attached to time out, we need to keep returning error
		// so as reconciler can not confirm this volume as attached.
		if nodeName == TimeoutAttachNode {
			return "", fmt.Errorf("timed out to attach volume %q to node %q", volumeName, nodeName)
		}
		if volumeNodes.Has(string(nodeName)) || volumeNodes.Has(MultiAttachNode) || nodeName == MultiAttachNode {
			volumeNodes.Insert(string(nodeName))
			return "/dev/vdb-test", nil
		}
		return "", fmt.Errorf("volume %q trying to attach to node %q is already attached to node %q", volumeName, nodeName, volumeNodes)
	}

	fv.VolumesAttached[volumeName] = sets.NewString(string(nodeName))
	if nodeName == UncertainAttachNode || nodeName == TimeoutAttachNode {
		return "", fmt.Errorf("timed out to attach volume %q to node %q", volumeName, nodeName)
	}
	return "/dev/vdb-test", nil
}

func (fv *FakeVolume) GetAttachCallCount() int {
	fv.RLock()
	defer fv.RUnlock()
	return fv.AttachCallCount
}

func (fv *FakeVolume) WaitForAttach(spec *Spec, devicePath string, pod *v1.Pod, spectimeout time.Duration) (string, error) {
	fv.Lock()
	defer fv.Unlock()
	fv.WaitForAttachCallCount++
	if fv.WaitForAttachHook != nil {
		return fv.WaitForAttachHook(spec, devicePath, pod, spectimeout)
	}
	return "/dev/sdb", nil
}

func (fv *FakeVolume) GetWaitForAttachCallCount() int {
	fv.RLock()
	defer fv.RUnlock()
	return fv.WaitForAttachCallCount
}

func (fv *FakeVolume) GetDeviceMountPath(spec *Spec) (string, error) {
	fv.Lock()
	defer fv.Unlock()
	fv.GetDeviceMountPathCallCount++
	return "", nil
}

func (fv *FakeVolume) mountDeviceInternal(spec *Spec, devicePath string, deviceMountPath string) error {
	fv.Lock()
	defer fv.Unlock()
	if spec.Name() == TimeoutOnMountDeviceVolumeName {
		fv.DeviceMountState[spec.Name()] = deviceMountUncertain
		return volumetypes.NewUncertainProgressError("mount failed")
	}

	if spec.Name() == FailMountDeviceVolumeName {
		fv.DeviceMountState[spec.Name()] = deviceNotMounted
		return fmt.Errorf("error mounting disk: %s", devicePath)
	}

	if spec.Name() == TimeoutAndFailOnMountDeviceVolumeName {
		_, ok := fv.DeviceMountState[spec.Name()]
		if !ok {
			fv.DeviceMountState[spec.Name()] = deviceMountUncertain
			return volumetypes.NewUncertainProgressError("timed out mounting error")
		}
		fv.DeviceMountState[spec.Name()] = deviceNotMounted
		return fmt.Errorf("error mounting disk: %s", devicePath)
	}

	if spec.Name() == SuccessAndTimeoutDeviceName {
		_, ok := fv.DeviceMountState[spec.Name()]
		if ok {
			fv.DeviceMountState[spec.Name()] = deviceMountUncertain
			return volumetypes.NewUncertainProgressError("error mounting state")
		}
	}

	if spec.Name() == SuccessAndFailOnMountDeviceName {
		_, ok := fv.DeviceMountState[spec.Name()]
		if ok {
			return fmt.Errorf("error mounting disk: %s", devicePath)
		}
	}
	fv.DeviceMountState[spec.Name()] = deviceMounted
	fv.MountDeviceCallCount++
	return nil
}

func (fv *FakeVolume) MountDevice(spec *Spec, devicePath string, deviceMountPath string, _ volume.DeviceMounterArgs) error {
	return fv.mountDeviceInternal(spec, devicePath, deviceMountPath)
}

func (fv *FakeVolume) GetMountDeviceCallCount() int {
	fv.RLock()
	defer fv.RUnlock()
	return fv.MountDeviceCallCount
}

func (fv *FakeVolume) GetUnmountDeviceCallCount() int {
	fv.RLock()
	defer fv.RUnlock()
	return fv.UnmountDeviceCallCount
}

func (fv *FakeVolume) Detach(volumeName string, nodeName types.NodeName) error {
	fv.Lock()
	defer fv.Unlock()
	fv.DetachCallCount++

	node := string(nodeName)
	volumeNodes, exist := fv.VolumesAttached[volumeName]
	if !exist || !volumeNodes.Has(node) {
		return fmt.Errorf("trying to detach volume %q that is not attached to the node %q", volumeName, node)
	}

	volumeNodes.Delete(node)
	if volumeNodes.Len() == 0 {
		delete(fv.VolumesAttached, volumeName)
	}

	return nil
}

func (fv *FakeVolume) VolumesAreAttached(spec []*Spec, nodeName types.NodeName) (map[*Spec]bool, error) {
	fv.Lock()
	defer fv.Unlock()
	return nil, nil
}

func (fv *FakeVolume) GetDetachCallCount() int {
	fv.RLock()
	defer fv.RUnlock()
	return fv.DetachCallCount
}

func (fv *FakeVolume) UnmountDevice(globalMountPath string) error {
	fv.Lock()
	defer fv.Unlock()
	fv.UnmountDeviceCallCount++
	if fv.UnmountDeviceHook != nil {
		return fv.UnmountDeviceHook(globalMountPath)
	}
	return nil
}

type FakeDeleter struct {
	path string
	MetricsNil
}

func (fd *FakeDeleter) Delete() error {
	// nil is success, else error
	return nil
}

func (fd *FakeDeleter) GetPath() string {
	return fd.path
}

type FakeProvisioner struct {
	Options               VolumeOptions
	Host                  VolumeHost
	ProvisionDelaySeconds int
}

func (fc *FakeProvisioner) Provision(selectedNode *v1.Node, allowedTopologies []v1.TopologySelectorTerm) (*v1.PersistentVolume, error) {
	// Add provision failure hook
	if fc.Options.Parameters != nil {
		if _, ok := fc.Options.Parameters[ExpectProvisionFailureKey]; ok {
			return nil, fmt.Errorf("expected error")
		}
	}
	fullpath := fmt.Sprintf("/tmp/hostpath_pv/%s", uuid.NewUUID())

	pv := &v1.PersistentVolume{
		ObjectMeta: metav1.ObjectMeta{
			Name: fc.Options.PVName,
			Annotations: map[string]string{
				util.VolumeDynamicallyCreatedByKey: "fakeplugin-provisioner",
			},
		},
		Spec: v1.PersistentVolumeSpec{
			PersistentVolumeReclaimPolicy: fc.Options.PersistentVolumeReclaimPolicy,
			AccessModes:                   fc.Options.PVC.Spec.AccessModes,
			Capacity: v1.ResourceList{
				v1.ResourceName(v1.ResourceStorage): fc.Options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)],
			},
			PersistentVolumeSource: v1.PersistentVolumeSource{
				HostPath: &v1.HostPathVolumeSource{
					Path: fullpath,
				},
			},
		},
	}

	if fc.ProvisionDelaySeconds > 0 {
		time.Sleep(time.Duration(fc.ProvisionDelaySeconds) * time.Second)
	}

	return pv, nil
}

var _ volumepathhandler.BlockVolumePathHandler = &FakeVolumePathHandler{}

//NewDeviceHandler Create a new IoHandler implementation
func NewBlockVolumePathHandler() volumepathhandler.BlockVolumePathHandler {
	return &FakeVolumePathHandler{}
}

type FakeVolumePathHandler struct {
	sync.RWMutex
}

func (fv *FakeVolumePathHandler) MapDevice(devicePath string, mapDir string, linkName string, bindMount bool) error {
	// nil is success, else error
	return nil
}

func (fv *FakeVolumePathHandler) UnmapDevice(mapDir string, linkName string, bindMount bool) error {
	// nil is success, else error
	return nil
}

func (fv *FakeVolumePathHandler) RemoveMapPath(mapPath string) error {
	// nil is success, else error
	return nil
}

func (fv *FakeVolumePathHandler) IsSymlinkExist(mapPath string) (bool, error) {
	// nil is success, else error
	return true, nil
}

func (fv *FakeVolumePathHandler) IsDeviceBindMountExist(mapPath string) (bool, error) {
	// nil is success, else error
	return true, nil
}

func (fv *FakeVolumePathHandler) GetDeviceBindMountRefs(devPath string, mapPath string) ([]string, error) {
	// nil is success, else error
	return []string{}, nil
}

func (fv *FakeVolumePathHandler) FindGlobalMapPathUUIDFromPod(pluginDir, mapPath string, podUID types.UID) (string, error) {
	// nil is success, else error
	return "", nil
}

func (fv *FakeVolumePathHandler) AttachFileDevice(path string) (string, error) {
	// nil is success, else error
	return "", nil
}

func (fv *FakeVolumePathHandler) DetachFileDevice(path string) error {
	// nil is success, else error
	return nil
}

func (fv *FakeVolumePathHandler) GetLoopDevice(path string) (string, error) {
	// nil is success, else error
	return "/dev/loop1", nil
}

// FindEmptyDirectoryUsageOnTmpfs finds the expected usage of an empty directory existing on
// a tmpfs filesystem on this system.
func FindEmptyDirectoryUsageOnTmpfs() (*resource.Quantity, error) {
	tmpDir, err := utiltesting.MkTmpdir("metrics_du_test")
	if err != nil {
		return nil, err
	}
	defer os.RemoveAll(tmpDir)
	out, err := exec.New().Command("nice", "-n", "19", "du", "-x", "-s", "-B", "1", tmpDir).CombinedOutput()
	if err != nil {
		return nil, fmt.Errorf("failed command 'du' on %s with error %v", tmpDir, err)
	}
	used, err := resource.ParseQuantity(strings.Fields(string(out))[0])
	if err != nil {
		return nil, fmt.Errorf("failed to parse 'du' output %s due to error %v", out, err)
	}
	used.Format = resource.BinarySI
	return &used, nil
}

// VerifyAttachCallCount ensures that at least one of the Attachers for this
// plugin has the expectedAttachCallCount number of calls. Otherwise it returns
// an error.
func VerifyAttachCallCount(
	expectedAttachCallCount int,
	fakeVolumePlugin *FakeVolumePlugin) error {
	for _, attacher := range fakeVolumePlugin.GetAttachers() {
		actualCallCount := attacher.GetAttachCallCount()
		if actualCallCount >= expectedAttachCallCount {
			return nil
		}
	}

	return fmt.Errorf(
		"No attachers have expected AttachCallCount. Expected: <%v>.",
		expectedAttachCallCount)
}

// VerifyZeroAttachCalls ensures that all of the Attachers for this plugin have
// a zero AttachCallCount. Otherwise it returns an error.
func VerifyZeroAttachCalls(fakeVolumePlugin *FakeVolumePlugin) error {
	for _, attacher := range fakeVolumePlugin.GetAttachers() {
		actualCallCount := attacher.GetAttachCallCount()
		if actualCallCount != 0 {
			return fmt.Errorf(
				"At least one attacher has non-zero AttachCallCount: <%v>.",
				actualCallCount)
		}
	}

	return nil
}

// VerifyWaitForAttachCallCount ensures that at least one of the Mounters for
// this plugin has the expectedWaitForAttachCallCount number of calls. Otherwise
// it returns an error.
func VerifyWaitForAttachCallCount(
	expectedWaitForAttachCallCount int,
	fakeVolumePlugin *FakeVolumePlugin) error {
	for _, attacher := range fakeVolumePlugin.GetAttachers() {
		actualCallCount := attacher.GetWaitForAttachCallCount()
		if actualCallCount >= expectedWaitForAttachCallCount {
			return nil
		}
	}

	return fmt.Errorf(
		"No Attachers have expected WaitForAttachCallCount. Expected: <%v>.",
		expectedWaitForAttachCallCount)
}

// VerifyZeroWaitForAttachCallCount ensures that all Attachers for this plugin
// have a zero WaitForAttachCallCount. Otherwise it returns an error.
func VerifyZeroWaitForAttachCallCount(fakeVolumePlugin *FakeVolumePlugin) error {
	for _, attacher := range fakeVolumePlugin.GetAttachers() {
		actualCallCount := attacher.GetWaitForAttachCallCount()
		if actualCallCount != 0 {
			return fmt.Errorf(
				"At least one attacher has non-zero WaitForAttachCallCount: <%v>.",
				actualCallCount)
		}
	}

	return nil
}

// VerifyMountDeviceCallCount ensures that at least one of the Mounters for
// this plugin has the expectedMountDeviceCallCount number of calls. Otherwise
// it returns an error.
func VerifyMountDeviceCallCount(
	expectedMountDeviceCallCount int,
	fakeVolumePlugin *FakeVolumePlugin) error {
	for _, attacher := range fakeVolumePlugin.GetAttachers() {
		actualCallCount := attacher.GetMountDeviceCallCount()
		if actualCallCount >= expectedMountDeviceCallCount {
			return nil
		}
	}

	return fmt.Errorf(
		"No Attachers have expected MountDeviceCallCount. Expected: <%v>.",
		expectedMountDeviceCallCount)
}

func VerifyUnmountDeviceCallCount(expectedCallCount int, fakeVolumePlugin *FakeVolumePlugin) error {
	detachers := fakeVolumePlugin.GetDetachers()
	if len(detachers) == 0 && (expectedCallCount == 0) {
		return nil
	}
	actualCallCount := 0
	for _, detacher := range detachers {
		actualCallCount = detacher.GetUnmountDeviceCallCount()
		if expectedCallCount == 0 && actualCallCount == expectedCallCount {
			return nil
		}

		if (expectedCallCount > 0) && (actualCallCount >= expectedCallCount) {
			return nil
		}
	}

	return fmt.Errorf(
		"Expected DeviceUnmount Call %d, got %d",
		expectedCallCount, actualCallCount)
}

// VerifyZeroMountDeviceCallCount ensures that all Attachers for this plugin
// have a zero MountDeviceCallCount. Otherwise it returns an error.
func VerifyZeroMountDeviceCallCount(fakeVolumePlugin *FakeVolumePlugin) error {
	for _, attacher := range fakeVolumePlugin.GetAttachers() {
		actualCallCount := attacher.GetMountDeviceCallCount()
		if actualCallCount != 0 {
			return fmt.Errorf(
				"At least one attacher has non-zero MountDeviceCallCount: <%v>.",
				actualCallCount)
		}
	}

	return nil
}

// VerifySetUpCallCount ensures that at least one of the Mounters for this
// plugin has the expectedSetUpCallCount number of calls. Otherwise it returns
// an error.
func VerifySetUpCallCount(
	expectedSetUpCallCount int,
	fakeVolumePlugin *FakeVolumePlugin) error {
	for _, mounter := range fakeVolumePlugin.GetMounters() {
		actualCallCount := mounter.GetSetUpCallCount()
		if actualCallCount >= expectedSetUpCallCount {
			return nil
		}
	}

	return fmt.Errorf(
		"No Mounters have expected SetUpCallCount. Expected: <%v>.",
		expectedSetUpCallCount)
}

// VerifyZeroSetUpCallCount ensures that all Mounters for this plugin have a
// zero SetUpCallCount. Otherwise it returns an error.
func VerifyZeroSetUpCallCount(fakeVolumePlugin *FakeVolumePlugin) error {
	for _, mounter := range fakeVolumePlugin.GetMounters() {
		actualCallCount := mounter.GetSetUpCallCount()
		if actualCallCount != 0 {
			return fmt.Errorf(
				"At least one mounter has non-zero SetUpCallCount: <%v>.",
				actualCallCount)
		}
	}

	return nil
}

// VerifyTearDownCallCount ensures that at least one of the Unounters for this
// plugin has the expectedTearDownCallCount number of calls. Otherwise it
// returns an error.
func VerifyTearDownCallCount(
	expectedTearDownCallCount int,
	fakeVolumePlugin *FakeVolumePlugin) error {
	unmounters := fakeVolumePlugin.GetUnmounters()
	if len(unmounters) == 0 && (expectedTearDownCallCount == 0) {
		return nil
	}

	for _, unmounter := range unmounters {
		actualCallCount := unmounter.GetTearDownCallCount()
		if expectedTearDownCallCount == 0 && actualCallCount == expectedTearDownCallCount {
			return nil
		}

		if (expectedTearDownCallCount > 0) && (actualCallCount >= expectedTearDownCallCount) {
			return nil
		}
	}

	return fmt.Errorf(
		"No Unmounters have expected SetUpCallCount. Expected: <%v>.",
		expectedTearDownCallCount)
}

// VerifyZeroTearDownCallCount ensures that all Mounters for this plugin have a
// zero TearDownCallCount. Otherwise it returns an error.
func VerifyZeroTearDownCallCount(fakeVolumePlugin *FakeVolumePlugin) error {
	for _, mounter := range fakeVolumePlugin.GetMounters() {
		actualCallCount := mounter.GetTearDownCallCount()
		if actualCallCount != 0 {
			return fmt.Errorf(
				"At least one mounter has non-zero TearDownCallCount: <%v>.",
				actualCallCount)
		}
	}

	return nil
}

// VerifyDetachCallCount ensures that at least one of the Attachers for this
// plugin has the expectedDetachCallCount number of calls. Otherwise it returns
// an error.
func VerifyDetachCallCount(
	expectedDetachCallCount int,
	fakeVolumePlugin *FakeVolumePlugin) error {
	for _, detacher := range fakeVolumePlugin.GetDetachers() {
		actualCallCount := detacher.GetDetachCallCount()
		if actualCallCount == expectedDetachCallCount {
			return nil
		}
	}

	return fmt.Errorf(
		"No Detachers have expected DetachCallCount. Expected: <%v>.",
		expectedDetachCallCount)
}

// VerifyZeroDetachCallCount ensures that all Detachers for this plugin have a
// zero DetachCallCount. Otherwise it returns an error.
func VerifyZeroDetachCallCount(fakeVolumePlugin *FakeVolumePlugin) error {
	for _, detacher := range fakeVolumePlugin.GetDetachers() {
		actualCallCount := detacher.GetDetachCallCount()
		if actualCallCount != 0 {
			return fmt.Errorf(
				"At least one detacher has non-zero DetachCallCount: <%v>.",
				actualCallCount)
		}
	}

	return nil
}

// VerifySetUpDeviceCallCount ensures that at least one of the Mappers for this
// plugin has the expectedSetUpDeviceCallCount number of calls. Otherwise it
// returns an error.
func VerifySetUpDeviceCallCount(
	expectedSetUpDeviceCallCount int,
	fakeVolumePlugin *FakeVolumePlugin) error {
	for _, mapper := range fakeVolumePlugin.GetBlockVolumeMapper() {
		actualCallCount := mapper.GetSetUpDeviceCallCount()
		if actualCallCount >= expectedSetUpDeviceCallCount {
			return nil
		}
	}

	return fmt.Errorf(
		"No Mapper have expected SetUpDeviceCallCount. Expected: <%v>.",
		expectedSetUpDeviceCallCount)
}

// VerifyTearDownDeviceCallCount ensures that at least one of the Unmappers for this
// plugin has the expectedTearDownDeviceCallCount number of calls. Otherwise it
// returns an error.
func VerifyTearDownDeviceCallCount(
	expectedTearDownDeviceCallCount int,
	fakeVolumePlugin *FakeVolumePlugin) error {
	for _, unmapper := range fakeVolumePlugin.GetBlockVolumeUnmapper() {
		actualCallCount := unmapper.GetTearDownDeviceCallCount()
		if actualCallCount >= expectedTearDownDeviceCallCount {
			return nil
		}
	}

	return fmt.Errorf(
		"No Unmapper have expected TearDownDeviceCallCount. Expected: <%v>.",
		expectedTearDownDeviceCallCount)
}

// VerifyZeroTearDownDeviceCallCount ensures that all Mappers for this plugin have a
// zero TearDownDeviceCallCount. Otherwise it returns an error.
func VerifyZeroTearDownDeviceCallCount(fakeVolumePlugin *FakeVolumePlugin) error {
	for _, unmapper := range fakeVolumePlugin.GetBlockVolumeUnmapper() {
		actualCallCount := unmapper.GetTearDownDeviceCallCount()
		if actualCallCount != 0 {
			return fmt.Errorf(
				"At least one unmapper has non-zero TearDownDeviceCallCount: <%v>.",
				actualCallCount)
		}
	}

	return nil
}

// VerifyUnmapPodDeviceCallCount ensures that at least one of the Unmappers for this
// plugin has the expected number of UnmapPodDevice calls. Otherwise it
// returns an error.
func VerifyUnmapPodDeviceCallCount(
	expectedUnmapPodDeviceCallCount int,
	fakeVolumePlugin *FakeVolumePlugin) error {
	for _, unmapper := range fakeVolumePlugin.GetBlockVolumeUnmapper() {
		actualCallCount := unmapper.GetUnmapPodDeviceCallCount()
		if actualCallCount >= expectedUnmapPodDeviceCallCount {
			return nil
		}
	}

	return fmt.Errorf(
		"No Unmapper have expected UnmapPodDeviceCallCount. Expected: <%v>.",
		expectedUnmapPodDeviceCallCount)
}

// VerifyZeroUnmapPodDeviceCallCount ensures that all Mappers for this plugin have a
// zero UnmapPodDevice calls. Otherwise it returns an error.
func VerifyZeroUnmapPodDeviceCallCount(fakeVolumePlugin *FakeVolumePlugin) error {
	for _, unmapper := range fakeVolumePlugin.GetBlockVolumeUnmapper() {
		actualCallCount := unmapper.GetUnmapPodDeviceCallCount()
		if actualCallCount != 0 {
			return fmt.Errorf(
				"At least one unmapper has non-zero UnmapPodDeviceCallCount: <%v>.",
				actualCallCount)
		}
	}

	return nil
}

// VerifyGetGlobalMapPathCallCount ensures that at least one of the Mappers for this
// plugin has the expectedGlobalMapPathCallCount number of calls. Otherwise it returns
// an error.
func VerifyGetGlobalMapPathCallCount(
	expectedGlobalMapPathCallCount int,
	fakeVolumePlugin *FakeVolumePlugin) error {
	for _, mapper := range fakeVolumePlugin.GetBlockVolumeMapper() {
		actualCallCount := mapper.GetGlobalMapPathCallCount()
		if actualCallCount == expectedGlobalMapPathCallCount {
			return nil
		}
	}

	return fmt.Errorf(
		"No Mappers have expected GetGlobalMapPathCallCount. Expected: <%v>.",
		expectedGlobalMapPathCallCount)
}

// VerifyGetPodDeviceMapPathCallCount ensures that at least one of the Mappers for this
// plugin has the expectedPodDeviceMapPathCallCount number of calls. Otherwise it returns
// an error.
func VerifyGetPodDeviceMapPathCallCount(
	expectedPodDeviceMapPathCallCount int,
	fakeVolumePlugin *FakeVolumePlugin) error {
	for _, mapper := range fakeVolumePlugin.GetBlockVolumeMapper() {
		actualCallCount := mapper.GetPodDeviceMapPathCallCount()
		if actualCallCount == expectedPodDeviceMapPathCallCount {
			return nil
		}
	}

	return fmt.Errorf(
		"No Mappers have expected GetPodDeviceMapPathCallCount. Expected: <%v>.",
		expectedPodDeviceMapPathCallCount)
}

// VerifyGetMapPodDeviceCallCount ensures that at least one of the Mappers for this
// plugin has the expectedMapPodDeviceCallCount number of calls. Otherwise it
// returns an error.
func VerifyGetMapPodDeviceCallCount(
	expectedMapPodDeviceCallCount int,
	fakeVolumePlugin *FakeVolumePlugin) error {
	for _, mapper := range fakeVolumePlugin.GetBlockVolumeMapper() {
		actualCallCount := mapper.GetMapPodDeviceCallCount()
		if actualCallCount >= expectedMapPodDeviceCallCount {
			return nil
		}
	}

	return fmt.Errorf(
		"No Mapper have expected MapPodDeviceCallCount. Expected: <%v>.",
		expectedMapPodDeviceCallCount)
}

// GetTestVolumePluginMgr creates, initializes, and returns a test volume plugin
// manager and fake volume plugin using a fake volume host.
func GetTestVolumePluginMgr(t *testing.T) (*VolumePluginMgr, *FakeVolumePlugin) {
	plugins := ProbeVolumePlugins(VolumeConfig{})
	v := NewFakeVolumeHost(
		t,
		"",      /* rootDir */
		nil,     /* kubeClient */
		plugins, /* plugins */
	)
	return v.GetPluginMgr(), plugins[0].(*FakeVolumePlugin)
}

func GetTestKubeletVolumePluginMgr(t *testing.T) (*VolumePluginMgr, *FakeVolumePlugin) {
	plugins := ProbeVolumePlugins(VolumeConfig{})
	v := NewFakeKubeletVolumeHost(
		t,
		"",      /* rootDir */
		nil,     /* kubeClient */
		plugins, /* plugins */
	)
	return v.GetPluginMgr(), plugins[0].(*FakeVolumePlugin)
}

// CreateTestPVC returns a provisionable PVC for tests
func CreateTestPVC(capacity string, accessModes []v1.PersistentVolumeAccessMode) *v1.PersistentVolumeClaim {
	claim := v1.PersistentVolumeClaim{
		ObjectMeta: metav1.ObjectMeta{
			Name:      "dummy",
			Namespace: "default",
		},
		Spec: v1.PersistentVolumeClaimSpec{
			AccessModes: accessModes,
			Resources: v1.ResourceRequirements{
				Requests: v1.ResourceList{
					v1.ResourceName(v1.ResourceStorage): resource.MustParse(capacity),
				},
			},
		},
	}
	return &claim
}

func MetricsEqualIgnoreTimestamp(a *Metrics, b *Metrics) bool {
	available := a.Available == b.Available
	capacity := a.Capacity == b.Capacity
	used := a.Used == b.Used
	inodes := a.Inodes == b.Inodes
	inodesFree := a.InodesFree == b.InodesFree
	inodesUsed := a.InodesUsed == b.InodesUsed
	return available && capacity && used && inodes && inodesFree && inodesUsed
}

func ContainsAccessMode(modes []v1.PersistentVolumeAccessMode, mode v1.PersistentVolumeAccessMode) bool {
	for _, m := range modes {
		if m == mode {
			return true
		}
	}
	return false
}


text:
QatarEnergy
Hazar Kilani
Global LNG supply is expected to increase by 3% to an estimated 415 million tonnes, while global LNG demand is predicted to increase by 2% to reach 401 million tonnes…
QatarEnergy joins Lebanon offshore exploration group
Asmahan Qarjouli
The development comes following a Washington mediation in the years-long maritime dispute between Beirut and Tel Aviv. QatarEnergy joined a tripartite oil and gas exploration consortium on Sunday in two…
Qatar FM sways away from energy minister's 'forgive and forget' remarks on Russia
The drop in Russian gas imports to Europe in turn strengthened Qatar's role as a top exporter of liquified natural gas. Qatar does not support a "forgive and forget" approach…
QatarEnergy, Chevron to build $6 billion gas-to-plastics plant
The project would ramp up Doha's overall petrochemical production to 14 million tonnes per annum. QatarEnergy announced the final investment decision with Chevron Phillips Chemical Company to build the $6…
Qatar, US top global LNG exports in 2022
Economists shared a positive economic outlook regarding Qatar as a major exporter of liquified natural gas (LNG). Qatar and the United States have topped global exports of LNG in 2022…
QatarEnergy, Sinopec ink major 27-year LNG agreement, longest of its kind in the industry
Four million tonnes of liquified natural gas (LNG) will be delivered to China through Qatar's North Field East (NFE) expansion project. QatarEnergy is supplying four million tonnes of liquified natural…
QatarEnergy renews oil production deal with Japan's Cosmo
Nadege Bizimungu
Under the terms of the five-year agreement, QPD, which is owned by Cosmo E&P and Sojitz, will continue to operate two oil fields in Qatar. QatarEnergy has signed an agreement…
Turkey's energy minister in Qatar in bid to boost cooperation
The International Monetary Fund forecasts say Qatar's economy growth is set to expand by 5.4% in 2022 alone and produce a surplus of roughly $45 billion. Qatar's Minister of State…
QatarEnergy to market 70% of gas at Texas facility
Several European nations turned to Doha in an effort to save their fragile energy supply, especially ahead of the cold winter season. QatarEnergy Trading is set to offtake, transport and…

redpajama_set_name: RedPajamaCommonCrawl


text:
Home Columns Unveiling The Number 19 Journey to Hawaii's Past Geological Ages and the Future World to Come
Journey to Hawaii's Past Geological Ages and the Future World to Come
Mother Tynnetta Muhammad
"And nothing prevents people from believing, when the guidance comes to them, except that they say: Has Allah raised up a mortal to be a messenger? Say: Had there been in the earth angels walking about secure, We would have sent down to them from the heaven an angel as messenger." —Holy Qur'an, Surah 17, verses 94-95
As I listened intently to Part I and II of the Honorable Minister Farrakhan's webcast address on "The Wheel"–Allah (God's) Calling Card," I tried to imagine what it might be like to be one of the pilots operating one of those 1,500 Baby Planes on board the Great Mother's Wheel. Each Baby Plane, according to the Divine Teachings of the Most Honorable Elijah Muhammad, is equipped with three bombs on board to be dropped over America at some future time. Each bomb carries a drill which upon entering the earth drills down one mile deep before its timed explosion. This area would cover a distance of 50 square miles and bring up a mountain one mile high all over America wherever these bombs are dropped. The only designated area of the world where this type of destruction would take place is America, with the exception of the British Isles, over which one of these Baby Planes is assigned to drop its bombs sometime in the near future.
According to Lesson Number 2, Question and Answer 39 of the Supreme Wisdom, we read: "–Now, tell us, would you hope to live to see that the Gods will take the Devil into hell in a very near future? ANS.–Yes. I fast and pray ALLAH, in the name of HIS Prophet, W.D. Fard, that I see the Hereafter when ALLAH in HIS own good time takes the Devil off our Planet." This type of destruction also coincides with the exploding of the atoms above our head cutting a shortage in the atmosphere producing fire. This type of fire would burn for 390 years nearly equal to the length of time that our foreparents were captured and forced into servitude slavery and bondage in America. After this terrific explosion of fire beginning in America, it would take 610 years to cool off. America would then be the new Eden or Paradise and Mecca of the New World Order or Kingdom of God on earth.
Thinking over these awesome events, my mind traveled to the exotic terrain of the Hawaiian islands which were produced by intense volcanic explosions spewing fire and lava flows that ultimately produced a natural environment of rainforests and waterfalls with lush vegetation on land and incredible sea life. Would America, after this severe burning and purification of her soil and atmosphere, become like the Hawaiian Islands 1,000 years from now? Will some of us live to see this reality through our offspring and unborn generations to come who would live in such a Paradise of a Future World?
A picturesque view of the Wailua Waterfalls and winding road to Hana and the famous Sacred Pools in Maui, Hawaii. Photos: wikipedia.com
All of the above thoughts came to me as I prepared this article to introduce the reflections and eyewitness account of Dr. Darnita Muhammad, one of my traveling companions, who described the high energy vibrations and spectacular environment that Hawaii has produced over thousands and millions of years of geological ages.
Reflections on Travel to Maui, December 2013
My third journey to Hawaii in a few short years was, once again, a life-changing experience that will not be forgotten. The first journey we had a group of seven with Mother Tynnetta traveling to Oahu, the capital Island of Hawaii at Honolulu and Maui. We set out to attend a healing conference and meeting which came by invitation from Sister Callie Muhammad. It is only by Allah's Grace and Mercy that I have found myself traveling each of these times with Mother Tynnetta and a few other sisters. I realize in these travels, more and more, Mother Tynnetta's beautiful example as a 'true' M.G.T. & G.C.C., a Spiritual Mother and a great witness of her husband, the Most Honorable Elijah Muhammad. The progression of these three journeys to Hawaii has appeared to take us deeper and deeper, closer and closer, to experiencing Allah's Presence; it is like moving into a vortex, as we witness Allah's Beauty, Wonder and Power.
Mother Tynnetta Muhammad, accompanied by Sister Callie Muhammad and Sister Darnita Muhammad, visiting the Temple of Peace wearing their Hawaiian Leis (flowered garlands). They participated in the health spa program and were featured speakers at their small gatherings on the island of Maui.
I often wondered how such a place so far away in the Pacific Ocean could be a part of the United States of America. Mother Tynnetta spoke of the future of these areas and islands from the Divine Teachings of the Most Honorable Elijah Muhammad, and now I better understand.
Honoring Mother Tynnetta's sister, Karlotta, was a highlight of this journey. In fact, Sister Karlotta's spirit and the memory of her during a heart-warming ceremony set the tone for this entire trip. The resonating words of indigenous families and other friends that knew of Sister Karlotta and Mother Tynnetta, produced an energy and vibratory frequency that would carry us over the next few days to high mountains of volcanic rock and sacred waters (pools). What drew someone like Sister Karlotta to Hawaii and specifically Maui? And why do others, Original men and women, or Caucasians, travel to this distant place and shore to 'fall in love'… and to find 'life' beyond our physical realities?
The winding 'Road to Hana' followed in the next series of events and the breathtaking beauty entrenched us for approximately 52 miles on this winding road. The climax of this meandering journey was the element of paradise we felt we had come to. The cascading waterfalls, the lush green trees that seemed to bow to us and the tranquil sounds of nature's delicate creatures was a reminder of our DNA genome map, that for the righteous, constantly evolves, healing and perfecting itself into that of Allah's Coding.
An inspirational finale was a visit, to the Temple of Peace, where Mother Tynnetta in five to ten minutes, spoke with grace and an outpouring of knowledge to a small group of diverse individuals. We were all humbled in the affirmation that the real temple of peace has to be in men and women.
I am in deep gratitude to Allah, in the Person of Master Fard Muhammad, the Most Honorable Elijah Muhammad, and the Honorable Minister Louis Farrakhan for our Divine Teachings, Guidance and Warning. And that by His Grace, we will be obedient, work harder, make our word bond and hear that small still voice within so that we might survive the wiles and snares of Satan and receive complete solace, healing and a place in the Hereafter. –By Sis. Darnita Muhammad, from Ft. Lauderdale, FL
"Say: Allah suffices for a witness between me and you. Surely He is ever Aware of His servants, Seeing." –Holy Qur'an, Surah 17, verse 96


Our core values are what make up our company culture here at AVKO. It's thanks to our staff having these core values that AVKO has been able to become the success that it is. We strive to include each and every value into every single day, to make our working lives more fun and enjoyable (after all, that's one of the values!).
Be a team player and respect each other.
This is our company. We are all part of the AVKO family.
Work should be enjoyable and fun.
Listen and then communicate in a respectful manner.
Founded in 1996 and an ISO 9001:2008 approved company since 2002, AVKO prides itself on its exceptional customer service and unrivalled knowledge of the specialist paint industry.
With a background rooted in the PVCu window industry, it was Chris Peeters who first recognised a significant lack of adaptable paint products in the professional marketplace. Armed with an extensive knowledge of the industry and its products, Chris set out to address this issue by creating a diverse range of colours and specialist finishes, establishing the unique business known today as AVKO.
From a small-scale business to a market leading brand, AVKO is continually developing its already extensive and innovative collection of specialist products. AVKO is also proud to offers its clients the most widely varied selection of professional products for PVCu, plastic, glass, metal and wood alongside an assortment of special effect finishes such as glitters and pearlescents.
Each and every member of the AVKO team is knowledgeable, dedicated and keen to provide the high level of technical advice and customer care that our clients have come to expect. Although the AVKO brand and team have grown dramatically over the years, the ethos of the business remains the same; we continue to regard our customers as our most important and valuable asset.


text:
До списку лускокрилих Андорри віднесено денних метеликів і молі, що були зареєстровані у  Андоррі.

Згідно з останніми оцінками, існує 885 видів лускокрилих, що зустрічаються на території Андорри.

Метелики

Hesperiidae
Carcharodus alceae (Esper, 1780)
Carcharodus floccifera (Zeller, 1847)
Erynnis tages (Linnaeus, 1758)
Hesperia comma (Linnaeus, 1758)
Pyrgus alveus (Hübner, 1803)
Pyrgus cacaliae (Rambur, 1839)
Pyrgus cirsii (Rambur, 1839)
Pyrgus malvae (Linnaeus, 1758)
Pyrgus serratulae (Rambur, 1839)
Thymelicus acteon (Rottemburg, 1775)
Thymelicus lineola (Ochsenheimer, 1808)
Thymelicus sylvestris (Poda, 1761)

Lycaenidae
Aricia agestis (Denis & Schiffermuller, 1775)
Aricia cramera Eschscholtz, 1821
Aricia nicias (Meigen, 1830)
Callophrys rubi (Linnaeus, 1758)
Cupido minimus (Fuessly, 1775)
Laeosopis roboris (Esper, 1789)
Lampides boeticus (Linnaeus, 1767)
Leptotes pirithous (Linnaeus, 1767)
Lycaena alciphron (Rottemburg, 1775)
Lycaena hippothoe (Linnaeus, 1761)
Lycaena phlaeas (Linnaeus, 1761)
Lycaena tityrus (Poda, 1761)
Lycaena virgaureae (Linnaeus, 1758)
Phengaris arion (Linnaeus, 1758)
Plebejus argus (Linnaeus, 1758)
Plebejus idas (Linnaeus, 1761)
Polyommatus damon (Denis & Schiffermuller, 1775)
Polyommatus bellargus (Rottemburg, 1775)
Polyommatus coridon (Poda, 1761)
Polyommatus hispana (Herrich-Schäffer, 1852)
Polyommatus daphnis (Denis & Schiffermuller, 1775)
Polyommatus amandus (Schneider, 1792)
Polyommatus dorylas (Denis & Schiffermuller, 1775)
Polyommatus eros (Ochsenheimer, 1808)
Polyommatus escheri (Hübner, 1823)
Polyommatus icarus (Rottemburg, 1775)
Satyrium spini (Denis & Schiffermuller, 1775)

Nymphalidae
Aglais io (Linnaeus, 1758)
Aglais urticae (Linnaeus, 1758)
Arethusana arethusa (Denis & Schiffermuller, 1775)
Argynnis paphia (Linnaeus, 1758)
Argynnis adippe (Denis & Schiffermuller, 1775)
Argynnis aglaja (Linnaeus, 1758)
Argynnis pandora (Denis & Schiffermuller, 1775)
Boloria eunomia (Esper, 1759)
Boloria napaea (Hoffmannsegg, 1804)
Boloria pales (Denis & Schiffermuller, 1775)
Boloria selene (Denis & Schiffermuller, 1775)
Brenthis daphne (Bergstrasser, 1780)
Brenthis ino (Rottemburg, 1775)
Brintesia circe (Fabricius, 1775)
Coenonympha arcania (Linnaeus, 1761)
Coenonympha dorus (Esper, 1782)
Erebia cassioides (Reiner & Hochenwarth, 1792)
Erebia epiphron (Knoch, 1783)
Erebia euryale (Esper, 1805)
Erebia gorgone Boisduval, 1833
Erebia hispania Butler, 1868
Erebia manto (Denis & Schiffermuller, 1775)
Erebia meolans (Prunner, 1798)
Erebia oeme (Hübner, 1804)
Erebia pandrose (Borkhausen, 1788)
Erebia rondoui Oberthur, 1908
Erebia triarius (de Prunner, 1798)
Hipparchia fagi (Scopoli, 1763)
Hipparchia hermione (Linnaeus, 1764)
Hipparchia semele (Linnaeus, 1758)
Issoria lathonia (Linnaeus, 1758)
Lasiommata maera (Linnaeus, 1758)
Lasiommata megera (Linnaeus, 1767)
Limenitis camilla (Linnaeus, 1764)
Limenitis reducta Staudinger, 1901
Maniola jurtina (Linnaeus, 1758)
Melanargia lachesis (Hübner, 1790)
Melitaea athalia (Rottemburg, 1775)
Melitaea cinxia (Linnaeus, 1758)
Melitaea deione (Geyer, 1832)
Melitaea didyma (Esper, 1778)
Melitaea parthenoides Keferstein, 1851
Melitaea phoebe (Denis & Schiffermuller, 1775)
Melitaea trivia (Denis & Schiffermuller, 1775)
Nymphalis antiopa (Linnaeus, 1758)
Polygonia c-album (Linnaeus, 1758)
Pyronia bathseba (Fabricius, 1793)
Pyronia tithonus (Linnaeus, 1767)
Satyrus actaea (Esper, 1781)
Vanessa atalanta (Linnaeus, 1758)
Vanessa cardui (Linnaeus, 1758)

Papilionidae
Iphiclides podalirius (Linnaeus, 1758)
Papilio machaon Linnaeus, 1758
Parnassius apollo (Linnaeus, 1758)
Parnassius mnemosyne (Linnaeus, 1758)

Pieridae
Anthocharis cardamines (Linnaeus, 1758)
Anthocharis euphenoides Staudinger, 1869
Aporia crataegi (Linnaeus, 1758)
Colias croceus (Fourcroy, 1785)
Colias phicomone (Esper, 1780)
Gonepteryx rhamni (Linnaeus, 1758)
Leptidea sinapis (Linnaeus, 1758)
Pieris brassicae (Linnaeus, 1758)
Pieris mannii (Mayer, 1851)
Pieris napi (Linnaeus, 1758)
Pieris rapae (Linnaeus, 1758)
Pontia callidice (Hübner, 1800)

Молі

Coleophoridae
Coleophora adelogrammella Zeller, 1849
Coleophora graminicolella Heinemann, 1876
Coleophora mayrella (Hübner, 1813)
Coleophora ribasella Baldizzone, 1982
Coleophora trifolii (Curtis, 1832)

Cosmopterigidae
Pancalia leuwenhoekella (Linnaeus, 1761)
Vulcaniella grabowiella (Staudinger, 1859)

Cossidae
Acossus terebra (Denis & Schiffermuller, 1775)
Cossus cossus (Linnaeus, 1758)
Dyspessa ulula (Borkhausen, 1790)
Zeuzera pyrina (Linnaeus, 1761)

Crambidae
Angustalius malacellus (Duponchel, 1836)
Catoptria digitellus (Herrich-Schäffer, 1849)
Catoptria falsella (Denis & Schiffermuller, 1775)
Crambus lathoniellus (Zincken, 1817)

Drepanidae
Achlya flavicornis (Linnaeus, 1758)
Cilix glaucata (Scopoli, 1763)
Cymatophorina diluta (Denis & Schiffermuller, 1775)
Falcaria lacertinaria (Linnaeus, 1758)
Ochropacha duplaris (Linnaeus, 1761)
Polyploca ridens (Fabricius, 1787)
Tethea ocularis (Linnaeus, 1767)
Thyatira batis (Linnaeus, 1758)
Watsonalla uncinula (Borkhausen, 1790)

Elachistidae
Elachista andorraensis Traugott-Olsen, 1988
Haplochrois buvati (Baldizzone, 1985)
Heinemannia festivella (Denis & Schiffermuller, 1775)

Endromidae
Endromis versicolora (Linnaeus, 1758)

Erebidae
Apaidia mesogona (Godart, 1824)
Arctia caja (Linnaeus, 1758)
Arctia villica (Linnaeus, 1758)
Atlantarctia tigrina (Villers, 1789)
Autophila dilucida (Hübner, 1808)
Autophila cataphanes (Hübner, 1813)
Callimorpha dominula (Linnaeus, 1758)
Calliteara pudibunda (Linnaeus, 1758)
Calyptra thalictri (Borkhausen, 1790)
Catephia alchymista (Denis & Schiffermuller, 1775)
Catocala coniuncta (Esper, 1787)
Catocala conversa (Esper, 1783)
Catocala elocata (Esper, 1787)
Catocala fraxini (Linnaeus, 1758)
Catocala nupta (Linnaeus, 1767)
Catocala nymphaea (Esper, 1787)
Catocala nymphagoga (Esper, 1787)
Catocala optata (Godart, 1824)
Catocala promissa (Denis & Schiffermuller, 1775)
Catocala puerpera (Giorna, 1791)
Chelis maculosa (Gerning, 1780)
Coscinia cribraria (Linnaeus, 1758)
Diacrisia sannio (Linnaeus, 1758)
Diaphora mendica (Clerck, 1759)
Dicallomera fascelina (Linnaeus, 1758)
Dysauxes punctata (Fabricius, 1781)
Dysgonia algira (Linnaeus, 1767)
Eilema griseola (Hübner, 1803)
Eilema lurideola (Zincken, 1817)
Eilema lutarella (Linnaeus, 1758)
Eilema palliatella (Scopoli, 1763)
Eilema pseudocomplana (Daniel, 1939)
Eilema pygmaeola (Doubleday, 1847)
Eilema sororcula (Hufnagel, 1766)
Eilema uniola (Rambur, 1866)
Eublemma candidana (Fabricius, 1794)
Eublemma ostrina (Hübner, 1808)
Eublemma parva (Hübner, 1808)
Eublemma polygramma (Duponchel, 1842)
Euclidia mi (Clerck, 1759)
Euclidia glyphica (Linnaeus, 1758)
Euplagia quadripunctaria (Poda, 1761)
Euproctis chrysorrhoea (Linnaeus, 1758)
Herminia tarsipennalis (Treitschke, 1835)
Hypena obesalis Treitschke, 1829
Hypena proboscidalis (Linnaeus, 1758)
Hyphoraia testudinaria (Geoffroy in Fourcroy, 1785)
Laspeyria flexula (Denis & Schiffermuller, 1775)
Leucoma salicis (Linnaeus, 1758)
Lithosia quadra (Linnaeus, 1758)
Lygephila craccae (Denis & Schiffermuller, 1775)
Lygephila pastinum (Treitschke, 1826)
Lymantria dispar (Linnaeus, 1758)
Lymantria monacha (Linnaeus, 1758)
Miltochrista miniata (Forster, 1771)
Minucia lunaris (Denis & Schiffermuller, 1775)
Ocneria rubea (Denis & Schiffermuller, 1775)
Ocnogyna zoraida (Graslin, 1837)
Paidia rica (Freyer, 1858)
Paracolax tristalis (Fabricius, 1794)
Parasemia plantaginis (Linnaeus, 1758)
Phragmatobia fuliginosa (Linnaeus, 1758)
Phragmatobia luctifera (Denis & Schiffermuller, 1775)
Phytometra viridaria (Clerck, 1759)
Rhyparia purpurata (Linnaeus, 1758)
Scoliopteryx libatrix (Linnaeus, 1758)
Setina flavicans (Geyer, 1836)
Setina irrorella (Linnaeus, 1758)
Spilosoma lubricipeda (Linnaeus, 1758)
Spilosoma lutea (Hufnagel, 1766)
Watsonarctia deserta (Bartel, 1902)
Zanclognatha lunalis (Scopoli, 1763)

Gelechiidae
Acompsia antirrhinella Milliere, 1866
Acompsia cinerella (Clerck, 1759)
Acompsia pyrenaella Huemer & Karsholt, 2002
Acompsia schmidtiellus (Heyden, 1848)
Bryotropha senectella (Zeller, 1839)
Bryotropha similis (Stainton, 1854)
Bryotropha terrella (Denis & Schiffermuller, 1775)
Carpatolechia fugitivella (Zeller, 1839)
Caryocolum albifaciella (Heinemann, 1870)
Caryocolum leucomelanella (Zeller, 1839)
Caryocolum mazeli Huemer & Nel, 2005
Dactylotula kinkerella (Snellen, 1876)
Exoteleia dodecella (Linnaeus, 1758)
Gelechia sororculella (Hübner, 1817)
Megacraspedus imparellus (Fischer von Röslerstamm, 1843)
Metzneria lappella (Linnaeus, 1758)
Recurvaria leucatella (Clerck, 1759)
Sattleria pyrenaica (Petry, 1904)
Scrobipalpa acuminatella (Sircom, 1850)
Scrobipalpa artemisiella (Treitschke, 1833)
Teleiopsis diffinis (Haworth, 1828)

Geometridae
Acasis viretata (Hübner, 1799)
Adactylotis gesticularia (Hübner, 1817)
Adalbertia castiliaria (Staudinger, 1900)
Aethalura punctulata (Denis & Schiffermuller, 1775)
Agriopis aurantiaria (Hübner, 1799)
Agriopis bajaria (Denis & Schiffermuller, 1775)
Agriopis leucophaearia (Denis & Schiffermuller, 1775)
Agriopis marginaria (Fabricius, 1776)
Alcis repandata (Linnaeus, 1758)
Aleucis distinctata (Herrich-Schäffer, 1839)
Alsophila aescularia (Denis & Schiffermuller, 1775)
Anticlea derivata (Denis & Schiffermuller, 1775)
Aplocera efformata (Guenee, 1858)
Aplocera plagiata (Linnaeus, 1758)
Aplocera praeformata (Hübner, 1826)
Apocheima hispidaria (Denis & Schiffermuller, 1775)
Aspitates gilvaria (Denis & Schiffermuller, 1775)
Asthena albulata (Hufnagel, 1767)
Biston betularia (Linnaeus, 1758)
Biston strataria (Hufnagel, 1767)
Bupalus piniaria (Linnaeus, 1758)
Cabera exanthemata (Scopoli, 1763)
Cabera pusaria (Linnaeus, 1758)
Calamodes occitanaria (Duponchel, 1829)
Campaea margaritaria (Linnaeus, 1761)
Camptogramma bilineata (Linnaeus, 1758)
Cataclysme uniformata (Bellier, 1862)
Catarhoe cuculata (Hufnagel, 1767)
Catarhoe rubidata (Denis & Schiffermuller, 1775)
Charissa obscurata (Denis & Schiffermuller, 1775)
Charissa crenulata (Staudinger, 1871)
Charissa mucidaria (Hübner, 1799)
Charissa ambiguata (Duponchel, 1830)
Charissa glaucinaria (Hübner, 1799)
Chemerina caliginearia (Rambur, 1833)
Chesias legatella (Denis & Schiffermuller, 1775)
Chesias rufata (Fabricius, 1775)
Chiasmia clathrata (Linnaeus, 1758)
Chlorissa cloraria (Hübner, 1813)
Chlorissa viridata (Linnaeus, 1758)
Chloroclysta miata (Linnaeus, 1758)
Chloroclysta siterata (Hufnagel, 1767)
Chloroclystis v-ata (Haworth, 1809)
Cidaria fulvata (Forster, 1771)
Cleora cinctaria (Denis & Schiffermuller, 1775)
Coenotephria tophaceata (Denis & Schiffermuller, 1775)
Colostygia aptata (Hübner, 1813)
Colostygia multistrigaria (Haworth, 1809)
Colostygia olivata (Denis & Schiffermuller, 1775)
Colostygia pectinataria (Knoch, 1781)
Colostygia turbata (Hübner, 1799)
Colotois pennaria (Linnaeus, 1761)
Comibaena bajularia (Denis & Schiffermuller, 1775)
Compsoptera opacaria (Hübner, 1819)
Cosmorhoe ocellata (Linnaeus, 1758)
Crocallis elinguaria (Linnaeus, 1758)
Crocallis tusciaria (Borkhausen, 1793)
Crocota peletieraria (Duponchel, 1830)
Cyclophora hyponoea (Prout, 1935)
Cyclophora suppunctaria (Zeller, 1847)
Cyclophora albiocellaria (Hübner, 1789)
Cyclophora albipunctata (Hufnagel, 1767)
Cyclophora puppillaria (Hübner, 1799)
Cyclophora quercimontaria (Bastelberger, 1897)
Dyscia lentiscaria (Donzel, 1837)
Dysstroma citrata (Linnaeus, 1761)
Dysstroma truncata (Hufnagel, 1767)
Earophila badiata (Denis & Schiffermuller, 1775)
Ecleora solieraria (Rambur, 1834)
Ecliptopera silaceata (Denis & Schiffermuller, 1775)
Electrophaes corylata (Thunberg, 1792)
Elophos dognini (Thierry-Mieg, 1910)
Ematurga atomaria (Linnaeus, 1758)
Ennomos alniaria (Linnaeus, 1758)
Ennomos fuscantaria (Haworth, 1809)
Ennomos quercaria (Hübner, 1813)
Entephria caeruleata (Guenee, 1858)
Entephria flavicinctata (Hübner, 1813)
Epione repandaria (Hufnagel, 1767)
Epione vespertaria (Linnaeus, 1767)
Epirrhoe alternata (Muller, 1764)
Epirrhoe galiata (Denis & Schiffermuller, 1775)
Epirrhoe molluginata (Hübner, 1813)
Epirrhoe rivata (Hübner, 1813)
Epirrhoe tristata (Linnaeus, 1758)
Epirrita autumnata (Borkhausen, 1794)
Epirrita christyi (Allen, 1906)
Epirrita dilutata (Denis & Schiffermuller, 1775)
Erannis defoliaria (Clerck, 1759)
Eulithis populata (Linnaeus, 1758)
Eulithis prunata (Linnaeus, 1758)
Euphyia biangulata (Haworth, 1809)
Euphyia frustata (Treitschke, 1828)
Eupithecia abbreviata Stephens, 1831
Eupithecia absinthiata (Clerck, 1759)
Eupithecia alliaria Staudinger, 1870
Eupithecia carpophagata Staudinger, 1871
Eupithecia centaureata (Denis & Schiffermuller, 1775)
Eupithecia cocciferata Milliere, 1864
Eupithecia denotata (Hübner, 1813)
Eupithecia distinctaria Herrich-Schäffer, 1848
Eupithecia dodoneata Guenee, 1858
Eupithecia extraversaria Herrich-Schäffer, 1852
Eupithecia haworthiata Doubleday, 1856
Eupithecia icterata (de Villers, 1789)
Eupithecia impurata (Hübner, 1813)
Eupithecia indigata (Hübner, 1813)
Eupithecia innotata (Hufnagel, 1767)
Eupithecia intricata (Zetterstedt, 1839)
Eupithecia irriguata (Hübner, 1813)
Eupithecia linariata (Denis & Schiffermuller, 1775)
Eupithecia massiliata Milliere, 1865
Eupithecia nanata (Hübner, 1813)
Eupithecia orphnata W. Petersen, 1909
Eupithecia oxycedrata (Rambur, 1833)
Eupithecia pauxillaria Boisduval, 1840
Eupithecia pimpinellata (Hübner, 1813)
Eupithecia plumbeolata (Haworth, 1809)
Eupithecia pulchellata Stephens, 1831
Eupithecia pusillata (Denis & Schiffermuller, 1775)
Eupithecia pyreneata Mabille, 1871
Eupithecia satyrata (Hübner, 1813)
Eupithecia semigraphata Bruand, 1850
Eupithecia silenata Assmann, 1848
Eupithecia subfuscata (Haworth, 1809)
Eupithecia subumbrata (Denis & Schiffermuller, 1775)
Eupithecia tantillaria Boisduval, 1840
Eupithecia tripunctaria Herrich-Schäffer, 1852
Eupithecia venosata (Fabricius, 1787)
Eupithecia veratraria Herrich-Schäffer, 1848
Eupithecia vulgata (Haworth, 1809)
Gandaritis pyraliata (Denis & Schiffermuller, 1775)
Geometra papilionaria (Linnaeus, 1758)
Glacies bentelii (Ratzer, 1890)
Gnophos obfuscata (Denis & Schiffermuller, 1775)
Gymnoscelis rufifasciata (Haworth, 1809)
Hemistola chrysoprasaria (Esper, 1795)
Horisme aemulata (Hübner, 1813)
Horisme radicaria (de La Harpe, 1855)
Horisme tersata (Denis & Schiffermuller, 1775)
Horisme vitalbata (Denis & Schiffermuller, 1775)
Hydriomena furcata (Thunberg, 1784)
Hydriomena ruberata (Freyer, 1831)
Hylaea fasciaria (Linnaeus, 1758)
Idaea alyssumata (Milliere, 1871)
Idaea aversata (Linnaeus, 1758)
Idaea calunetaria (Staudinger, 1859)
Idaea cervantaria (Milliere, 1869)
Idaea contiguaria (Hübner, 1799)
Idaea degeneraria (Hübner, 1799)
Idaea deversaria (Herrich-Schäffer, 1847)
Idaea dilutaria (Hübner, 1799)
Idaea eugeniata (Dardoin & Milliere, 1870)
Idaea fuscovenosa (Goeze, 1781)
Idaea humiliata (Hufnagel, 1767)
Idaea incalcarata (Chretien, 1913)
Idaea luteolaria (Constant, 1863)
Idaea mediaria (Hübner, 1819)
Idaea moniliata (Denis & Schiffermuller, 1775)
Idaea obsoletaria (Rambur, 1833)
Idaea ochrata (Scopoli, 1763)
Idaea ostrinaria (Hübner, 1813)
Idaea rubraria (Staudinger, 1901)
Idaea rufaria (Hübner, 1799)
Idaea rusticata (Denis & Schiffermuller, 1775)
Idaea squalidaria (Staudinger, 1882)
Idaea straminata (Borkhausen, 1794)
Idaea subsaturata (Guenee, 1858)
Idaea subsericeata (Haworth, 1809)
Isturgia limbaria (Fabricius, 1775)
Isturgia miniosaria (Duponchel, 1829)
Isturgia murinaria (Denis & Schiffermuller, 1775)
Jodis lactearia (Linnaeus, 1758)
Lampropteryx suffumata (Denis & Schiffermuller, 1775)
Ligdia adustata (Denis & Schiffermuller, 1775)
Lobophora halterata (Hufnagel, 1767)
Lomaspilis marginata (Linnaeus, 1758)
Lycia hirtaria (Clerck, 1759)
Lythria cruentaria (Hufnagel, 1767)
Macaria brunneata (Thunberg, 1784)
Macaria liturata (Clerck, 1759)
Menophra abruptaria (Thunberg, 1792)
Menophra nycthemeraria (Geyer, 1831)
Mesotype didymata (Linnaeus, 1758)
Mesotype verberata (Scopoli, 1763)
Minoa murinata (Scopoli, 1763)
Nebula achromaria (de La Harpe, 1853)
Nebula nebulata (Treitschke, 1828)
Nychiodes andalusiaria Staudinger, 1892
Nycterosea obstipata (Fabricius, 1794)
Odezia atrata (Linnaeus, 1758)
Odontopera bidentata (Clerck, 1759)
Onychora agaritharia (Dardoin, 1842)
Operophtera brumata (Linnaeus, 1758)
Operophtera fagata (Scharfenberg, 1805)
Opisthograptis luteolata (Linnaeus, 1758)
Ourapteryx sambucaria (Linnaeus, 1758)
Pasiphila rectangulata (Linnaeus, 1758)
Pennithera firmata (Hübner, 1822)
Peribatodes abstersaria (Boisduval, 1840)
Peribatodes ilicaria (Geyer, 1833)
Peribatodes perversaria (Boisduval, 1840)
Peribatodes powelli (Oberthur, 1913)
Peribatodes rhomboidaria (Denis & Schiffermuller, 1775)
Peribatodes subflavaria (Milliere, 1876)
Perizoma albulata (Denis & Schiffermuller, 1775)
Perizoma alchemillata (Linnaeus, 1758)
Perizoma bifaciata (Haworth, 1809)
Perizoma blandiata (Denis & Schiffermuller, 1775)
Perizoma flavosparsata (Wagner, 1926)
Perizoma hydrata (Treitschke, 1829)
Perizoma lugdunaria (Herrich-Schäffer, 1855)
Perizoma obsoletata (Herrich-Schäffer, 1838)
Petrophora narbonea (Linnaeus, 1767)
Phigalia pilosaria (Denis & Schiffermuller, 1775)
Philereme vetulata (Denis & Schiffermuller, 1775)
Plagodis pulveraria (Linnaeus, 1758)
Problepsis ocellata (Frivaldszky, 1845)
Pseudopanthera macularia (Linnaeus, 1758)
Pseudoterpna coronillaria (Hübner, 1817)
Psodos quadrifaria (Sulzer, 1776)
Pungeleria capreolaria (Denis & Schiffermuller, 1775)
Rheumaptera hastata (Linnaeus, 1758)
Rhodometra sacraria (Linnaeus, 1767)
Rhodostrophia calabra (Petagna, 1786)
Rhodostrophia vibicaria (Clerck, 1759)
Rhoptria asperaria (Hübner, 1817)
Sciadia tenebraria (Esper, 1806)
Scopula asellaria (Herrich-Schäffer, 1847)
Scopula floslactata (Haworth, 1809)
Scopula imitaria (Hübner, 1799)
Scopula incanata (Linnaeus, 1758)
Scopula marginepunctata (Goeze, 1781)
Scopula rufomixtaria (de Graslin, 1863)
Scopula immorata (Linnaeus, 1758)
Scopula ornata (Scopoli, 1763)
Scopula submutata (Treitschke, 1828)
Scotopteryx angularia (de Villers, 1789)
Scotopteryx bipunctaria (Denis & Schiffermuller, 1775)
Scotopteryx chenopodiata (Linnaeus, 1758)
Scotopteryx coelinaria (de Graslin, 1863)
Scotopteryx luridata (Hufnagel, 1767)
Scotopteryx moeniata (Scopoli, 1763)
Scotopteryx mucronata (Scopoli, 1763)
Scotopteryx octodurensis (Favre, 1903)
Scotopteryx peribolata (Hübner, 1817)
Selenia dentaria (Fabricius, 1775)
Selenia lunularia (Hübner, 1788)
Selidosema brunnearia (de Villers, 1789)
Selidosema taeniolaria (Hübner, 1813)
Siona lineata (Scopoli, 1763)
Spargania luctuata (Denis & Schiffermuller, 1775)
Stegania trimaculata (de Villers, 1789)
Tephronia oranaria Staudinger, 1892
Tephronia sepiaria (Hufnagel, 1767)
Thalera fimbrialis (Scopoli, 1763)
Thera britannica (Turner, 1925)
Thera cognata (Thunberg, 1792)
Thera obeliscata (Hübner, 1787)
Thera variata (Denis & Schiffermuller, 1775)
Theria primaria (Haworth, 1809)
Thetidia smaragdaria (Fabricius, 1787)
Timandra comae Schmidt, 1931
Trichopteryx carpinata (Borkhausen, 1794)
Triphosa dubitata (Linnaeus, 1758)
Triphosa sabaudiata (Duponchel, 1830)
Xanthorhoe designata (Hufnagel, 1767)
Xanthorhoe fluctuata (Linnaeus, 1758)
Xanthorhoe montanata (Denis & Schiffermuller, 1775)
Xanthorhoe spadicearia (Denis & Schiffermuller, 1775)

Hepialidae
Pharmacis fusconebulosa (DeGeer, 1778)
Pharmacis pyrenaicus (Donzel, 1838)
Triodia sylvina (Linnaeus, 1761)

Heterogynidae
Heterogynis penella (Hübner, 1819)

Lasiocampidae
Dendrolimus pini (Linnaeus, 1758)
Gastropacha quercifolia (Linnaeus, 1758)
Gastropacha populifolia (Denis & Schiffermuller, 1775)
Lasiocampa quercus (Linnaeus, 1758)
Lasiocampa trifolii (Denis & Schiffermuller, 1775)
Macrothylacia rubi (Linnaeus, 1758)
Malacosoma castrensis (Linnaeus, 1758)
Malacosoma neustria (Linnaeus, 1758)
Poecilocampa populi (Linnaeus, 1758)
Trichiura crataegi (Linnaeus, 1758)

Momphidae
Mompha miscella (Denis & Schiffermuller, 1775)

Nepticulidae
Stigmella ilicifoliella (Mendes, 1918)

Noctuidae
Abrostola asclepiadis (Denis & Schiffermuller, 1775)
Abrostola triplasia (Linnaeus, 1758)
Acontia lucida (Hufnagel, 1766)
Acronicta leporina (Linnaeus, 1758)
Acronicta alni (Linnaeus, 1767)
Acronicta psi (Linnaeus, 1758)
Acronicta auricoma (Denis & Schiffermuller, 1775)
Acronicta euphorbiae (Denis & Schiffermuller, 1775)
Acronicta rumicis (Linnaeus, 1758)
Actinotia polyodon (Clerck, 1759)
Actinotia radiosa (Esper, 1804)
Agrochola lychnidis (Denis & Schiffermuller, 1775)
Agrochola helvola (Linnaeus, 1758)
Agrochola litura (Linnaeus, 1758)
Agrochola lunosa (Haworth, 1809)
Agrochola lota (Clerck, 1759)
Agrochola macilenta (Hübner, 1809)
Agrochola circellaris (Hufnagel, 1766)
Agrotis bigramma (Esper, 1790)
Agrotis cinerea (Denis & Schiffermuller, 1775)
Agrotis clavis (Hufnagel, 1766)
Agrotis exclamationis (Linnaeus, 1758)
Agrotis ipsilon (Hufnagel, 1766)
Agrotis puta (Hübner, 1803)
Agrotis segetum (Denis & Schiffermuller, 1775)
Agrotis simplonia (Geyer, 1832)
Agrotis trux (Hübner, 1824)
Allophyes alfaroi Agenjo, 1951
Ammoconia caecimacula (Denis & Schiffermuller, 1775)
Ammopolia witzenmanni (Standfuss, 1890)
Amphipoea oculea (Linnaeus, 1761)
Amphipyra berbera Rungs, 1949
Amphipyra effusa Boisduval, 1828
Amphipyra pyramidea (Linnaeus, 1758)
Amphipyra tragopoginis (Clerck, 1759)
Amphipyra cinnamomea (Goeze, 1781)
Anaplectoides prasina (Denis & Schiffermuller, 1775)
Anarta myrtilli (Linnaeus, 1761)
Anarta odontites (Boisduval, 1829)
Anarta pugnax (Hübner, 1824)
Anarta trifolii (Hufnagel, 1766)
Anorthoa munda (Denis & Schiffermuller, 1775)
Antitype chi (Linnaeus, 1758)
Apamea crenata (Hufnagel, 1766)
Apamea furva (Denis & Schiffermuller, 1775)
Apamea lateritia (Hufnagel, 1766)
Apamea lithoxylaea (Denis & Schiffermuller, 1775)
Apamea maillardi (Geyer, 1834)
Apamea monoglypha (Hufnagel, 1766)
Apamea platinea (Treitschke, 1825)
Apamea sordens (Hufnagel, 1766)
Apamea sublustris (Esper, 1788)
Aporophyla nigra (Haworth, 1809)
Apterogenum ypsillon (Denis & Schiffermuller, 1775)
Atethmia centrago (Haworth, 1809)
Athetis pallustris (Hübner, 1808)
Autographa bractea (Denis & Schiffermuller, 1775)
Autographa gamma (Linnaeus, 1758)
Autographa jota (Linnaeus, 1758)
Autographa pulchrina (Haworth, 1809)
Axylia putris (Linnaeus, 1761)
Brachylomia viminalis (Fabricius, 1776)
Bryonycta pineti (Staudinger, 1859)
Bryophila raptricula (Denis & Schiffermuller, 1775)
Bryophila ravula (Hübner, 1813)
Bryophila domestica (Hufnagel, 1766)
Bryophila microglossa (Rambur, 1858)
Callopistria latreillei (Duponchel, 1827)
Calophasia lunula (Hufnagel, 1766)
Calophasia platyptera (Esper, 1788)
Caradrina clavipalpis Scopoli, 1763
Caradrina flavirena Guenee, 1852
Caradrina selini Boisduval, 1840
Caradrina aspersa Rambur, 1834
Ceramica pisi (Linnaeus, 1758)
Cerapteryx graminis (Linnaeus, 1758)
Cerastis rubricosa (Denis & Schiffermuller, 1775)
Charanyca ferruginea (Esper, 1785)
Chersotis alpestris (Boisduval, 1837)
Chersotis cuprea (Denis & Schiffermuller, 1775)
Chersotis margaritacea (Villers, 1789)
Chersotis multangula (Hübner, 1803)
Chersotis ocellina (Denis & Schiffermuller, 1775)
Chloantha hyperici (Denis & Schiffermuller, 1775)
Cleonymia yvanii (Duponchel, 1833)
Colocasia coryli (Linnaeus, 1758)
Conisania luteago (Denis & Schiffermuller, 1775)
Conistra daubei (Duponchel, 1838)
Conistra gallica (Lederer, 1857)
Conistra rubiginosa (Scopoli, 1763)
Conistra vaccinii (Linnaeus, 1761)
Conistra erythrocephala (Denis & Schiffermuller, 1775)
Conistra rubiginea (Denis & Schiffermuller, 1775)
Conistra staudingeri (Graslin, 1863)
Conistra torrida (Lederer, 1857)
Cosmia trapezina (Linnaeus, 1758)
Cosmia affinis (Linnaeus, 1767)
Craniophora pontica (Staudinger, 1878)
Cryphia algae (Fabricius, 1775)
Cucullia absinthii (Linnaeus, 1761)
Cucullia campanulae Freyer, 1831
Cucullia lucifuga (Denis & Schiffermuller, 1775)
Cucullia umbratica (Linnaeus, 1758)
Cucullia xeranthemi Boisduval, 1840
Cucullia scrophulariae (Denis & Schiffermuller, 1775)
Cucullia verbasci (Linnaeus, 1758)
Dasypolia templi (Thunberg, 1792)
Diachrysia chrysitis (Linnaeus, 1758)
Diarsia guadarramensis (Boursin, 1928)
Dichagyris flammatra (Denis & Schiffermuller, 1775)
Dichagyris musiva (Hübner, 1803)
Dichagyris candelisequa (Denis & Schiffermuller, 1775)
Dichagyris constanti (Milliere, 1860)
Dichagyris forcipula (Denis & Schiffermuller, 1775)
Dichagyris nigrescens (Hofner, 1888)
Dichagyris renigera (Hübner, 1808)
Dicycla oo (Linnaeus, 1758)
Diloba caeruleocephala (Linnaeus, 1758)
Dryobota labecula (Esper, 1788)
Dryobotodes tenebrosa (Esper, 1789)
Dryobotodes eremita (Fabricius, 1775)
Dryobotodes monochroma (Esper, 1790)
Dryobotodes roboris (Geyer, 1835)
Dypterygia scabriuscula (Linnaeus, 1758)
Egira conspicillaris (Linnaeus, 1758)
Enargia paleacea (Esper, 1788)
Epilecta linogrisea (Denis & Schiffermuller, 1775)
Epipsilia grisescens (Fabricius, 1794)
Eremobia ochroleuca (Denis & Schiffermuller, 1775)
Eremohadena halimi (Milliere, 1877)
Euchalcia variabilis (Piller, 1783)
Eugnorisma glareosa (Esper, 1788)
Eugnorisma depuncta (Linnaeus, 1761)
Eupsilia transversa (Hufnagel, 1766)
Eurois occulta (Linnaeus, 1758)
Euxoa aquilina (Denis & Schiffermuller, 1775)
Euxoa conspicua (Hübner, 1824)
Euxoa decora (Denis & Schiffermuller, 1775)
Euxoa nigricans (Linnaeus, 1761)
Euxoa obelisca (Denis & Schiffermuller, 1775)
Euxoa recussa (Hübner, 1817)
Euxoa temera (Hübner, 1808)
Euxoa tritici (Linnaeus, 1761)
Griposia aprilina (Linnaeus, 1758)
Hada plebeja (Linnaeus, 1761)
Hadena perplexa (Denis & Schiffermuller, 1775)
Hadena ruetimeyeri Boursin, 1951
Hadena albimacula (Borkhausen, 1792)
Hadena bicruris (Hufnagel, 1766)
Hadena caesia (Denis & Schiffermuller, 1775)
Hadena compta (Denis & Schiffermuller, 1775)
Hadena confusa (Hufnagel, 1766)
Hadena filograna (Esper, 1788)
Hadena magnolii (Boisduval, 1829)
Hecatera bicolorata (Hufnagel, 1766)
Hecatera dysodea (Denis & Schiffermuller, 1775)
Helicoverpa armigera (Hübner, 1808)
Heliothis peltigera (Denis & Schiffermuller, 1775)
Heliothis viriplaca (Hufnagel, 1766)
Hoplodrina ambigua (Denis & Schiffermuller, 1775)
Hoplodrina blanda (Denis & Schiffermuller, 1775)
Hoplodrina octogenaria (Goeze, 1781)
Hoplodrina respersa (Denis & Schiffermuller, 1775)
Hoplodrina superstes (Ochsenheimer, 1816)
Ipimorpha subtusa (Denis & Schiffermuller, 1775)
Jodia croceago (Denis & Schiffermuller, 1775)
Lacanobia thalassina (Hufnagel, 1766)
Lacanobia oleracea (Linnaeus, 1758)
Lacanobia w-latinum (Hufnagel, 1766)
Lasionycta imbecilla (Fabricius, 1794)
Lasionycta proxima (Hübner, 1809)
Lateroligia ophiogramma (Esper, 1794)
Leucania loreyi (Duponchel, 1827)
Leucania comma (Linnaeus, 1761)
Leucochlaena oditis (Hübner, 1822)
Lithophane furcifera (Hufnagel, 1766)
Lithophane ornitopus (Hufnagel, 1766)
Lithophane semibrunnea (Haworth, 1809)
Lithophane leautieri (Boisduval, 1829)
Litoligia literosa (Haworth, 1809)
Lophoterges millierei (Staudinger, 1871)
Luperina nickerlii (Freyer, 1845)
Luperina testacea (Denis & Schiffermuller, 1775)
Lycophotia porphyrea (Denis & Schiffermuller, 1775)
Mamestra brassicae (Linnaeus, 1758)
Melanchra persicariae (Linnaeus, 1761)
Mesapamea secalella Remm, 1983
Mesapamea secalis (Linnaeus, 1758)
Mesogona acetosellae (Denis & Schiffermuller, 1775)
Mesoligia furuncula (Denis & Schiffermuller, 1775)
Mniotype adusta (Esper, 1790)
Mormo maura (Linnaeus, 1758)
Mythimna albipuncta (Denis & Schiffermuller, 1775)
Mythimna ferrago (Fabricius, 1787)
Mythimna l-album (Linnaeus, 1767)
Mythimna conigera (Denis & Schiffermuller, 1775)
Mythimna impura (Hübner, 1808)
Mythimna vitellina (Hübner, 1808)
Mythimna unipuncta (Haworth, 1809)
Mythimna sicula (Treitschke, 1835)
Noctua comes Hübner, 1813
Noctua fimbriata (Schreber, 1759)
Noctua interjecta Hübner, 1803
Noctua interposita (Hübner, 1790)
Noctua janthina Denis & Schiffermuller, 1775
Noctua pronuba (Linnaeus, 1758)
Noctua tirrenica Biebinger, Speidel & Hanigk, 1983
Nyctobrya muralis (Forster, 1771)
Ochropleura leucogaster (Freyer, 1831)
Ochropleura plecta (Linnaeus, 1761)
Oligia fasciuncula (Haworth, 1809)
Oligia latruncula (Denis & Schiffermuller, 1775)
Oligia strigilis (Linnaeus, 1758)
Olivenebula xanthochloris (Boisduval, 1840)
Omia cymbalariae (Hübner, 1809)
Orthosia gracilis (Denis & Schiffermuller, 1775)
Orthosia cerasi (Fabricius, 1775)
Orthosia cruda (Denis & Schiffermuller, 1775)
Orthosia populeti (Fabricius, 1775)
Orthosia incerta (Hufnagel, 1766)
Orthosia gothica (Linnaeus, 1758)
Pachetra sagittigera (Hufnagel, 1766)
Panchrysia v-argenteum (Esper, 1798)
Panemeria tenebrata (Scopoli, 1763)
Panolis flammea (Denis & Schiffermuller, 1775)
Papestra biren (Goeze, 1781)
Parastichtis suspecta (Hübner, 1817)
Peridroma saucia (Hübner, 1808)
Phlogophora meticulosa (Linnaeus, 1758)
Polia hepatica (Clerck, 1759)
Polia nebulosa (Hufnagel, 1766)
Polychrysia moneta (Fabricius, 1787)
Polymixis argillaceago (Hübner, 1822)
Polymixis dubia (Duponchel, 1836)
Polymixis xanthomista (Hübner, 1819)
Protolampra sobrina (Duponchel, 1843)
Rhizedra lutosa (Hübner, 1803)
Rhyacia helvetina (Boisduval, 1833)
Rhyacia lucipeta (Denis & Schiffermuller, 1775)
Sideridis rivularis (Fabricius, 1775)
Sideridis reticulata (Goeze, 1781)
Spaelotis ravida (Denis & Schiffermuller, 1775)
Spaelotis senna (Freyer, 1829)
Spodoptera exigua (Hübner, 1808)
Stilbia anomala (Haworth, 1812)
Subacronicta megacephala (Denis & Schiffermuller, 1775)
Syngrapha interrogationis (Linnaeus, 1758)
Thalpophila vitalba (Freyer, 1834)
Tholera decimalis (Poda, 1761)
Trigonophora haasi (Staudinger, 1892)
Trigonophora flammea (Esper, 1785)
Trigonophora jodea (Herrich-Schäffer, 1850)
Tyta luctuosa (Denis & Schiffermuller, 1775)
Valeria jaspidea (Villers, 1789)
Xanthia gilvago (Denis & Schiffermuller, 1775)
Xanthia icteritia (Hufnagel, 1766)
Xanthia ocellaris (Borkhausen, 1792)
Xanthia ruticilla (Esper, 1791)
Xanthia togata (Esper, 1788)
Xestia ashworthii (Doubleday, 1855)
Xestia c-nigrum (Linnaeus, 1758)
Xestia triangulum (Hufnagel, 1766)
Xestia agathina (Duponchel, 1827)
Xestia baja (Denis & Schiffermuller, 1775)
Xestia castanea (Esper, 1798)
Xestia xanthographa (Denis & Schiffermuller, 1775)
Xylena exsoleta (Linnaeus, 1758)
Xylocampa areola (Esper, 1789)

Nolidae
Bena bicolorana (Fuessly, 1775)
Meganola strigula (Denis & Schiffermuller, 1775)
Nola cicatricalis (Treitschke, 1835)
Nola cucullatella (Linnaeus, 1758)
Nola subchlamydula Staudinger, 1871
Pseudoips prasinana (Linnaeus, 1758)

Notodontidae
Cerura iberica (Templado & Ortiz, 1966)
Clostera anachoreta (Denis & Schiffermuller, 1775)
Clostera pigra (Hufnagel, 1766)
Drymonia querna (Denis & Schiffermuller, 1775)
Furcula bifida (Brahm, 1787)
Harpyia milhauseri (Fabricius, 1775)
Notodonta dromedarius (Linnaeus, 1767)
Notodonta tritophus (Denis & Schiffermuller, 1775)
Notodonta ziczac (Linnaeus, 1758)
Peridea anceps (Goeze, 1781)
Phalera bucephala (Linnaeus, 1758)
Pheosia gnoma (Fabricius, 1776)
Pheosia tremula (Clerck, 1759)
Pterostoma palpina (Clerck, 1759)
Ptilodon capucina (Linnaeus, 1758)
Rhegmatophila alpina (Bellier, 1881)
Stauropus fagi (Linnaeus, 1758)
Thaumetopoea pityocampa (Denis & Schiffermuller, 1775)

Psychidae
Penestoglossa pyrenaella Herrmann, 2006
Pseudobankesia casaella Hattenschwiler, 1994

Pterophoridae
Marasmarcha oxydactylus (Staudinger, 1859)
Merrifieldia leucodactyla (Denis & Schiffermuller, 1775)
Stenoptilia pelidnodactyla (Stein, 1837)
Stenoptilia pterodactyla (Linnaeus, 1761)
Stenoptilia zophodactylus (Duponchel, 1840)

Saturniidae
Actias isabellae (Graells, 1849)
Saturnia pavonia (Linnaeus, 1758)
Saturnia pyri (Denis & Schiffermuller, 1775)

Scythrididae
Enolmis acanthella (Godart, 1824)
Scythris obscurella (Scopoli, 1763)
Scythris picaepennis (Haworth, 1828)
Scythris subseliniella (Heinemann, 1876)

Sesiidae
Chamaesphecia bibioniformis (Esper, 1800)
Pyropteron chrysidiformis (Esper, 1782)
Sesia apiformis (Clerck, 1759)

Sphingidae
Acherontia atropos (Linnaeus, 1758)
Agrius convolvuli (Linnaeus, 1758)
Deilephila elpenor (Linnaeus, 1758)
Deilephila porcellus (Linnaeus, 1758)
Hemaris tityus (Linnaeus, 1758)
Hippotion celerio (Linnaeus, 1758)
Hyles euphorbiae (Linnaeus, 1758)
Hyles livornica (Esper, 1780)
Laothoe populi (Linnaeus, 1758)
Macroglossum stellatarum (Linnaeus, 1758)
Mimas tiliae (Linnaeus, 1758)
Proserpinus proserpina (Pallas, 1772)
Smerinthus ocellata (Linnaeus, 1758)
Sphinx ligustri Linnaeus, 1758
Sphinx maurorum (Jordan, 1931)
Sphinx pinastri Linnaeus, 1758

Thyrididae
Thyris fenestrella (Scopoli, 1763)

Tineidae
Ateliotum petrinella (Herrich-Schäffer, 1854)
Eudarcia gallica (Petersen, 1962)
Infurcitinea atrifasciella (Staudinger, 1871)
Infurcitinea roesslerella (Heyden, 1865)
Monopis obviella (Denis & Schiffermuller, 1775)
Myrmecozela ochraceella (Tengstrom, 1848)
Niditinea fuscella (Linnaeus, 1758)

Tortricidae
Aethes cnicana (Westwood, 1854)
Aethes margaritana (Haworth, 1811)
Aethes tesserana (Denis & Schiffermuller, 1775)
Clavigesta sylvestrana (Curtis, 1850)
Cnephasia stephensiana (Doubleday, 1849)
Cochylis atricapitana (Stephens, 1852)
Cochylis hybridella (Hübner, 1813)
Dichrorampha harpeana Frey, 1870
Eana argentana (Clerck, 1759)
Endothenia gentianaeana (Hübner, 1799)
Epinotia ramella (Linnaeus, 1758)
Eucosma pupillana (Clerck, 1759)
Eulia ministrana (Linnaeus, 1758)
Eupoecilia angustana (Hübner, 1799)
Grapholita molesta (Busck, 1916)
Hedya pruniana (Hübner, 1799)
Metendothenia atropunctana (Zetterstedt, 1839)
Notocelia cynosbatella (Linnaeus, 1758)
Notocelia roborana (Denis & Schiffermuller, 1775)
Pammene aurana (Fabricius, 1775)
Phtheochroa frigidana (Guenee, 1845)
Rhopobota naevana (Hübner, 1817)
Tortrix viridana Linnaeus, 1758

Zygaenidae
Adscita geryon (Hübner, 1813)
Adscita statices (Linnaeus, 1758)
Aglaope infausta (Linnaeus, 1767)
Jordanita globulariae (Hübner, 1793)
Zygaena carniolica (Scopoli, 1763)
Zygaena fausta (Linnaeus, 1767)
Zygaena hilaris Ochsenheimer, 1808
Zygaena purpuralis (Brunnich, 1763)
Zygaena sarpedon (Hübner, 1790)
Zygaena anthyllidis Boisduval, 1828
Zygaena exulans (Hohenwarth, 1792)
Zygaena filipendulae (Linnaeus, 1758)
Zygaena lonicerae (Scheven, 1777)
Zygaena loti (Denis & Schiffermuller, 1775)
Zygaena nevadensis Rambur, 1858
Zygaena osterodensis Reiss, 1921
Zygaena transalpina (Esper, 1780)

Посилання
European Butterflies and Moths
Fauna Europaea

Фауна Андорри
А
Списки:Андорра

redpajama_set_name: RedPajamaWikipedia


HomeWhat a year – and it gets better….!
Congrats. The Doctor is IN !!!! Have known a lot of those folks for years. Great team. You will be a very complimentary addition !!
Congratulations, PSC is getting a great developer, as well as someone who obviously really enjoys sharing his knowledge.
We are going to miss you here @ MAXIMUS!
This year really has been better than I could have possibly imagined – with so many new friends and colleagues in the community, the opportunities have opened up for me.
This is in a large part because of the encouragement I have received for you guys and everyone else I have met.
I am truly grateful and humbled!
Congratulations Mark. Really appreciate the help you gave me recently. Hope it all goes well in your new job.


... low cost of manufacture and use. ... ZENITH has earned high reputation among our customers. ... Raymond Mill Raymond Mill.
gypsum raymond mill with having a long standing … Crusher For Sale China Low Cost Raymond Mill Manufacturer With High Reputation High . ... long service life raymond mill .
Raymond Mill; LM Vertical Grinding Mills; ... High-frequency Screen; LSX Sand Washing Machine; ... home >> cost of a raymond mill.
china low cost raymond mill manufacturer with high reputation. Raymond Impact Mill worldcrusher. raymond impact mill for Low Cost Grinding of aNEW Company is a grinder mills ,vertical mills ,MTM and SCM mills manufacturer in China .
china cost effective ore raymond mill grinder for selling. china low cost raymond mill manufacturer with high reputation. ... We are the Chinese Limestone grinder mill in .
Low Operation Cost Raymond Mill Factory, Manufacturers, Suppliers From China, Therefore, we can meet different inquiries from different consumers. You should find our web page to check additional info from our products.
High Efficiency Raymond Mill From China Manufacturer … High Efficiency Raymond Mill From China Manufacturer for ... new type high efficiency and low cost raymond mill.