#! /usr/bin/perl -w
# nagios: -epn

package Monitoring::GLPlugin::Commandline::Getopt;
use strict;
use File::Basename;
use Getopt::Long qw(:config no_ignore_case bundling);

# Standard defaults
my %DEFAULT = (
  timeout => 15,
  verbose => 0,
  license =>
"This monitoring plugin is free software, and comes with ABSOLUTELY NO WARRANTY.
It may be used, redistributed and/or modified under the terms of the GNU
General Public Licence (see http://www.fsf.org/licensing/licenses/gpl.txt).",
);
# Standard arguments
my @ARGS = ({
    spec => 'usage|?',
    help => "-?, --usage\n   Print usage information",
  }, {
    spec => 'help|h',
    help => "-h, --help\n   Print detailed help screen",
  }, {
    spec => 'version|V',
    help => "-V, --version\n   Print version information",
  }, {
    #spec => 'extra-opts:s@',
    #help => "--extra-opts=[<section>[@<config_file>]]\n   Section and/or config_file from which to load extra options (may repeat)",
  }, {
    spec => 'timeout|t=i',
    help => sprintf("-t, --timeout=INTEGER\n   Seconds before plugin times out (default: %s)", $DEFAULT{timeout}),
    default => $DEFAULT{timeout},
  }, {
    spec => 'verbose|v+',
    help => "-v, --verbose\n   Show details for command-line debugging (can repeat up to 3 times)",
    default => $DEFAULT{verbose},
  },
);
# Standard arguments we traditionally display last in the help output
my %DEFER_ARGS = map { $_ => 1 } qw(timeout verbose);

sub _init {
  my ($self, %params) = @_;
  # Check params
  my %attr = (
    usage => 1,
    version => 0,
    url => 0,
    plugin => { default => $Monitoring::GLPlugin::pluginname },
    blurb => 0,
    extra => 0,
    'extra-opts' => 0,
    license => { default => $DEFAULT{license} },
    timeout => { default => $DEFAULT{timeout} },
  );

  # Add attr to private _attr hash (except timeout)
  $self->{timeout} = delete $attr{timeout};
  $self->{_attr} = { %attr };
  foreach (keys %{$self->{_attr}}) {
    if (exists $params{$_}) {
      $self->{_attr}->{$_} = $params{$_};
    } else {
      $self->{_attr}->{$_} = $self->{_attr}->{$_}->{default}
          if ref ($self->{_attr}->{$_}) eq 'HASH' &&
              exists $self->{_attr}->{$_}->{default};
    }
  }
  # Chomp _attr values
  chomp foreach values %{$self->{_attr}};

  # Setup initial args list
  $self->{_args} = [ grep { exists $_->{spec} } @ARGS ];

  $self
}

sub new {
  my ($class, @params) = @_;
  my $self = bless {}, $class;
  $self->_init(@params);
}

sub add_arg {
  my ($self, %arg) = @_;
  push (@{$self->{_args}}, \%arg);
}

sub mod_arg {
  my ($self, $argname, %arg) = @_;
  foreach my $old_arg (@{$self->{_args}}) {
    next unless $old_arg->{spec} =~ /(\w+).*/ && $argname eq $1;
    foreach my $key (keys %arg) {
      $old_arg->{$key} = $arg{$key};
    }
  }
}

sub getopts {
  my ($self) = @_;
  my %commandline = ();
  my @params = map { $_->{spec} } @{$self->{_args}};
  if (! GetOptions(\%commandline, @params)) {
    $self->print_help();
    exit 0;
  } else {
    no strict 'refs';
    no warnings 'redefine';
    do { $self->print_help(); exit 0; } if $commandline{help};
    do { $self->print_version(); exit 0 } if $commandline{version};
    do { $self->print_usage(); exit 3 } if $commandline{usage};
    foreach (map { $_->{spec} =~ /^([\w\-]+)/; $1; } @{$self->{_args}}) {
      my $field = $_;
      *{"$field"} = sub {
        return $self->{opts}->{$field};
      };
    }
    foreach (map { $_->{spec} =~ /^([\w\-]+)/; $1; }
        grep { exists $_->{required} && $_->{required} } @{$self->{_args}}) {
      do { $self->print_usage(); exit 0 } if ! exists $commandline{$_};
    }
    foreach (grep { exists $_->{default} } @{$self->{_args}}) {
      $_->{spec} =~ /^([\w\-]+)/;
      my $spec = $1;
      $self->{opts}->{$spec} = $_->{default};
    }
    foreach (keys %commandline) {
      $self->{opts}->{$_} = $commandline{$_};
    }
    foreach (grep { exists $_->{env} } @{$self->{_args}}) {
      $_->{spec} =~ /^([\w\-]+)/;
      my $spec = $1;
      if (exists $ENV{'NAGIOS__HOST'.$_->{env}}) {
        $self->{opts}->{$spec} = $ENV{'NAGIOS__HOST'.$_->{env}};
      }
      if (exists $ENV{'NAGIOS__SERVICE'.$_->{env}}) {
        $self->{opts}->{$spec} = $ENV{'NAGIOS__SERVICE'.$_->{env}};
      }
    }
    foreach (grep { exists $_->{aliasfor} } @{$self->{_args}}) {
      my $field = $_->{aliasfor};
      $_->{spec} =~ /^([\w\-]+)/;
      my $aliasfield = $1;
      next if $self->{opts}->{$field};
      *{"$field"} = sub {
        return $self->{opts}->{$aliasfield};
      };
    }
  }
}

sub create_opt {
  my ($self, $key) = @_;
  no strict 'refs';
  *{"$key"} = sub {
      return $self->{opts}->{$key};
  };
}

sub override_opt {
  my ($self, $key, $value) = @_;
  $self->{opts}->{$key} = $value;
}

sub get {
  my ($self, $opt) = @_;
  return $self->{opts}->{$opt};
}

sub print_help {
  my ($self) = @_;
  $self->print_version();
  printf "\n%s\n", $self->{_attr}->{license};
  printf "\n%s\n\n", $self->{_attr}->{blurb};
  $self->print_usage();
  foreach (grep {
      ! (exists $_->{hidden} && $_->{hidden}) 
  } @{$self->{_args}}) {
    printf " %s\n", $_->{help};
  }
  exit 0;
}

sub print_usage {
  my ($self) = @_;
  printf $self->{_attr}->{usage}, $self->{_attr}->{plugin};
  print "\n";
}

sub print_version {
  my ($self) = @_;
  printf "%s %s", $self->{_attr}->{plugin}, $self->{_attr}->{version};
  printf " [%s]", $self->{_attr}->{url} if $self->{_attr}->{url};
  print "\n";
}

sub print_license {
  my ($self) = @_;
  printf "%s\n", $self->{_attr}->{license};
  print "\n";
}



package Monitoring::GLPlugin::Commandline;
use strict;
use IO::File;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3, DEPENDENT => 4 };
our %ERRORS = (
    'OK'        => OK,
    'WARNING'   => WARNING,
    'CRITICAL'  => CRITICAL,
    'UNKNOWN'   => UNKNOWN,
    'DEPENDENT' => DEPENDENT,
);

our %STATUS_TEXT = reverse %ERRORS;
our $AUTOLOAD;


sub new {
  my ($class, %params) = @_;
  require Monitoring::GLPlugin::Commandline::Getopt
      if ! grep /BEGIN/, keys %Monitoring::GLPlugin::Commandline::Getopt::;
  my $self = {
       perfdata => [],
       messages => {
         ok => [],
         warning => [],
         critical => [],
         unknown => [],
       },
       args => [],
       opts => Monitoring::GLPlugin::Commandline::Getopt->new(%params),
       modes => [],
       statefilesdir => undef,
  };
  foreach (qw(shortname usage version url plugin blurb extra
      license timeout)) {
    $self->{$_} = $params{$_};
  }
  bless $self, $class;
  $self->{plugin} ||= $Monitoring::GLPlugin::pluginname;
  $self->{name} = $self->{plugin};
  $Monitoring::GLPlugin::plugin = $self;
}

sub AUTOLOAD {
  my ($self, @params) = @_;
  return if ($AUTOLOAD =~ /DESTROY/);
  $self->debug("AUTOLOAD %s\n", $AUTOLOAD)
        if $self->{opts}->verbose >= 2;
  if ($AUTOLOAD =~ /^.*::(add_arg|override_opt|create_opt)$/) {
    $self->{opts}->$1(@params);
  }
}

sub DESTROY {
  my ($self) = @_;
  # ohne dieses DESTROY rennt nagios_exit in obiges AUTOLOAD rein
  # und fliegt aufs Maul, weil {opts} bereits nicht mehr existiert.
  # Unerklaerliches Verhalten.
}

sub debug {
  my ($self, $format, @message) = @_;
  my $tracefile = "/tmp/".$Monitoring::GLPlugin::pluginname.".trace";
  $self->{trace} = -f $tracefile ? 1 : 0;
  if ($self->opts->verbose && $self->opts->verbose > 10) {
    printf("%s: ", scalar localtime);
    printf($format, @message);
    printf "\n";
  }
  if ($self->{trace}) {
    my $logfh = IO::File->new();
    $logfh->autoflush(1);
    if ($logfh->open($tracefile, "a")) {
      $logfh->printf("%s: ", scalar localtime);
      $logfh->printf($format, @message);
      $logfh->printf("\n");
      $logfh->close();
    }
  }
}

sub opts {
  my ($self) = @_;
  return $self->{opts};
}

sub getopts {
  my ($self) = @_;
  $self->opts->getopts();
}

sub add_message {
  my ($self, $code, @messages) = @_;
  $code = (qw(ok warning critical unknown))[$code] if $code =~ /^\d+$/;
  $code = lc $code;
  push @{$self->{messages}->{$code}}, @messages;
}

sub selected_perfdata {
  my ($self, $label) = @_;
  if ($self->opts->can("selectedperfdata") && $self->opts->selectedperfdata) {
    my $pattern = $self->opts->selectedperfdata;
    return ($label =~ /$pattern/i) ? 1 : 0;
  } else {
    return 1;
  }
}

sub add_perfdata {
  my ($self, %args) = @_;
#printf "add_perfdata %s\n", Data::Dumper::Dumper(\%args);
#printf "add_perfdata %s\n", Data::Dumper::Dumper($self->{thresholds});
#
# wenn warning, critical, dann wird von oben ein expliziter wert mitgegeben
# wenn thresholds
#  wenn label in 
#    warningx $self->{thresholds}->{$label}->{warning} existiert
#  dann nimm $self->{thresholds}->{$label}->{warning}
#  ansonsten thresholds->default->warning
#

  my $label = $args{label};
  my $value = $args{value};
  my $uom = $args{uom} || "";
  my $format = '%d';

  if ($self->opts->can("morphperfdata") && $self->opts->morphperfdata) {
    # 'Intel [R] Interface (\d+) usage'='nic$1'
    foreach my $key (keys %{$self->opts->morphperfdata}) {
      if ($label =~ /$key/) {
        my $replacement = '"'.$self->opts->morphperfdata->{$key}.'"';
        my $oldlabel = $label;
        $label =~ s/$key/$replacement/ee;
        if (exists $self->{thresholds}->{$oldlabel}) {
          %{$self->{thresholds}->{$label}} = %{$self->{thresholds}->{$oldlabel}};
        }
      }
    }
  }
  if ($value =~ /\./) {
    if (defined $args{places}) {
      $value = sprintf '%.'.$args{places}.'f', $value;
    } else {
      $value = sprintf "%.2f", $value;
    }
  } else {
    $value = sprintf "%d", $value;
  }
  my $warn = "";
  my $crit = "";
  my $min = defined $args{min} ? $args{min} : "";
  my $max = defined $args{max} ? $args{max} : "";
  if ($args{thresholds} || (! exists $args{warning} && ! exists $args{critical})) {
    if (exists $self->{thresholds}->{$label}->{warning}) {
      $warn = $self->{thresholds}->{$label}->{warning};
    } elsif (exists $self->{thresholds}->{default}->{warning}) {
      $warn = $self->{thresholds}->{default}->{warning};
    }
    if (exists $self->{thresholds}->{$label}->{critical}) {
      $crit = $self->{thresholds}->{$label}->{critical};
    } elsif (exists $self->{thresholds}->{default}->{critical}) {
      $crit = $self->{thresholds}->{default}->{critical};
    }
  } else {
    if ($args{warning}) {
      $warn = $args{warning};
    }
    if ($args{critical}) {
      $crit = $args{critical};
    }
  }
  if ($uom eq "%") {
    $min = 0;
    $max = 100;
  }
  if (defined $args{places}) {
    # cut off excessive decimals which may be the result of a division
    # length = places*2, no trailing zeroes
    if ($warn ne "") {
      $warn = join("", map {
          s/\.0+$//; $_
      } map {
          s/(\.[1-9]+)0+$/$1/; $_
      } map {
          /[\+\-\d\.]+/ ? sprintf '%.'.2*$args{places}.'f', $_ : $_;
      } split(/([\+\-\d\.]+)/, $warn));
    }
    if ($crit ne "") {
      $crit = join("", map {
          s/\.0+$//; $_
      } map {
          s/(\.[1-9]+)0+$/$1/; $_
      } map {
          /[\+\-\d\.]+/ ? sprintf '%.'.2*$args{places}.'f', $_ : $_;
      } split(/([\+\-\d\.]+)/, $crit));
    }
    if ($min ne "") {
      $min = join("", map {
          s/\.0+$//; $_
      } map {
          s/(\.[1-9]+)0+$/$1/; $_
      } map {
          /[\+\-\d\.]+/ ? sprintf '%.'.2*$args{places}.'f', $_ : $_;
      } split(/([\+\-\d\.]+)/, $min));
    }
    if ($max ne "") {
      $max = join("", map {
          s/\.0+$//; $_
      } map {
          s/(\.[1-9]+)0+$/$1/; $_
      } map {
          /[\+\-\d\.]+/ ? sprintf '%.'.2*$args{places}.'f', $_ : $_;
      } split(/([\+\-\d\.]+)/, $max));
    }
  }
  push @{$self->{perfdata}}, sprintf("'%s'=%s%s;%s;%s;%s;%s",
      $label, $value, $uom, $warn, $crit, $min, $max)
      if $self->selected_perfdata($label);
}

sub add_html {
  my ($self, $line) = @_;
  push @{$self->{html}}, $line;
}

sub suppress_messages {
  my ($self) = @_;
  $self->{suppress_messages} = 1;
}

sub clear_messages {
  my ($self, $code) = @_;
  $code = (qw(ok warning critical unknown))[$code] if $code =~ /^\d+$/;
  $code = lc $code;
  $self->{messages}->{$code} = [];
}

sub reduce_messages_short {
  my ($self, $message) = @_;
  $message ||= "no problems";
  if ($self->opts->report && $self->opts->report eq "short") {
    $self->clear_messages(OK);
    $self->add_message(OK, $message) if ! $self->check_messages();
  }
}

sub reduce_messages {
  my ($self, $message) = @_;
  $message ||= "no problems";
  $self->clear_messages(OK);
  $self->add_message(OK, $message) if ! $self->check_messages();
}

sub check_messages {
  my ($self, %args) = @_;

  # Add object messages to any passed in as args
  for my $code (qw(critical warning unknown ok)) {
    my $messages = $self->{messages}->{$code} || [];
    if ($args{$code}) {
      unless (ref $args{$code} eq 'ARRAY') {
        if ($code eq 'ok') {
          $args{$code} = [ $args{$code} ];
        }
      }
      push @{$args{$code}}, @$messages;
    } else {
      $args{$code} = $messages;
    }
  }
  my %arg = %args;
  $arg{join} = ' ' unless defined $arg{join};

  # Decide $code
  my $code = OK;
  $code ||= CRITICAL  if @{$arg{critical}};
  $code ||= WARNING   if @{$arg{warning}};
  $code ||= UNKNOWN   if @{$arg{unknown}};
  return $code unless wantarray;

  # Compose message
  my $message = '';
  if ($arg{join_all}) {
      $message = join( $arg{join_all},
          map { @$_ ? join( $arg{'join'}, @$_) : () }
              $arg{critical},
              $arg{warning},
              $arg{unknown},
              $arg{ok} ? (ref $arg{ok} ? $arg{ok} : [ $arg{ok} ]) : []
      );
  }

  else {
      $message ||= join( $arg{'join'}, @{$arg{critical}} )
          if $code == CRITICAL;
      $message ||= join( $arg{'join'}, @{$arg{warning}} )
          if $code == WARNING;
      $message ||= join( $arg{'join'}, @{$arg{unknown}} )
          if $code == UNKNOWN;
      $message ||= ref $arg{ok} ? join( $arg{'join'}, @{$arg{ok}} ) : $arg{ok}
          if $arg{ok};
  }

  return ($code, $message);
}

sub status_code {
  my ($self, $code) = @_;
  $code = (qw(ok warning critical unknown))[$code] if $code =~ /^\d+$/;
  $code = uc $code;
  $code = $ERRORS{$code} if defined $code && exists $ERRORS{$code};
  $code = UNKNOWN unless defined $code && exists $STATUS_TEXT{$code};
  return "$STATUS_TEXT{$code}";
}

sub perfdata_string {
  my ($self) = @_;
  if (scalar (@{$self->{perfdata}})) {
    return join(" ", @{$self->{perfdata}});
  } else {
    return "";
  }
}

sub html_string {
  my ($self) = @_;
  if (scalar (@{$self->{html}})) {
    return join(" ", @{$self->{html}});
  } else {
    return "";
  }
}

sub nagios_exit {
  my ($self, $code, $message, $arg) = @_;
  $code = $ERRORS{$code} if defined $code && exists $ERRORS{$code};
  $code = UNKNOWN unless defined $code && exists $STATUS_TEXT{$code};
  $message = '' unless defined $message;
  if (ref $message && ref $message eq 'ARRAY') {
      $message = join(' ', map { chomp; $_ } @$message);
  } else {
      chomp $message;
  }
  if ($self->opts->negate) {
    my $original_code = $code;
    foreach my $from (keys %{$self->opts->negate}) {
      if ((uc $from) =~ /^(OK|WARNING|CRITICAL|UNKNOWN)$/ &&
          (uc $self->opts->negate->{$from}) =~ /^(OK|WARNING|CRITICAL|UNKNOWN)$/) {
        if ($original_code == $ERRORS{uc $from}) {
          $code = $ERRORS{uc $self->opts->negate->{$from}};
        }
      }
    }
  }
  my $output = "$STATUS_TEXT{$code}";
  $output .= " - $message" if defined $message && $message ne '';
  if ($self->opts->can("morphmessage") && $self->opts->morphmessage) {
    # 'Intel [R] Interface (\d+) usage'='nic$1'
    # '^OK.*'="alles klar"   '^CRITICAL.*'="alles hi"
    foreach my $key (keys %{$self->opts->morphmessage}) {
      if ($output =~ /$key/) {
        my $replacement = '"'.$self->opts->morphmessage->{$key}.'"';
        $output =~ s/$key/$replacement/ee;
      }
    }
  }
  $output =~ s/\|/!/g if $output;
  if (scalar (@{$self->{perfdata}})) {
    $output .= " | ".$self->perfdata_string();
  }
  $output .= "\n";
  if ($self->opts->can("isvalidtime") && ! $self->opts->isvalidtime) {
    $code = OK;
    $output = "OK - outside valid timerange. check results are not relevant now. original message was: ".
        $output;
  }
  if (! exists $self->{suppress_messages}) {
    print $output;
  }
  exit $code;
}

sub set_thresholds {
  my ($self, %params) = @_;
  if (exists $params{metric}) {
    my $metric = $params{metric};
    # erst die hartcodierten defaultschwellwerte
    $self->{thresholds}->{$metric}->{warning} = $params{warning};
    $self->{thresholds}->{$metric}->{critical} = $params{critical};
    # dann die defaultschwellwerte von der kommandozeile
    if (defined $self->opts->warning) {
      $self->{thresholds}->{$metric}->{warning} = $self->opts->warning;
    }
    if (defined $self->opts->critical) {
      $self->{thresholds}->{$metric}->{critical} = $self->opts->critical;
    }
    # dann die ganz spezifischen schwellwerte von der kommandozeile
    if ($self->opts->warningx) { # muss nicht auf defined geprueft werden, weils ein hash ist
      # Erst schauen, ob einer * beinhaltet. Von denen wird vom Laengsten
      # bis zum Kuerzesten probiert, ob die matchen. Der laengste Match
      # gewinnt.
      my @keys = keys %{$self->opts->warningx};
      my @stringkeys = ();
      my @regexkeys = ();
      foreach my $key (sort { length($b) > length($a) } @keys) {
        if ($key =~ /\*/) {
          push(@regexkeys, $key);
        } else {
          push(@stringkeys, $key);
        }
      }
      foreach my $key (@regexkeys) {
        next if $metric !~ /$key/;
        $self->{thresholds}->{$metric}->{warning} = $self->opts->warningx->{$key};
        last;
      }
      # Anschliessend nochmal schauen, ob es einen nicht-Regex-Volltreffer gibt
      foreach my $key (@stringkeys) {
        next if $key ne $metric;
        $self->{thresholds}->{$metric}->{warning} = $self->opts->warningx->{$key};
        last;
      }
    }
    if ($self->opts->criticalx) {
      my @keys = keys %{$self->opts->criticalx};
      my @stringkeys = ();
      my @regexkeys = ();
      foreach my $key (sort { length($b) > length($a) } @keys) {
        if ($key =~ /\*/) {
          push(@regexkeys, $key);
        } else {
          push(@stringkeys, $key);
        }
      }
      foreach my $key (@regexkeys) {
        next if $metric !~ /$key/;
        $self->{thresholds}->{$metric}->{critical} = $self->opts->criticalx->{$key};
        last;
      }
      # Anschliessend nochmal schauen, ob es einen nicht-Regex-Volltreffer gibt
      foreach my $key (@stringkeys) {
        next if $key ne $metric;
        $self->{thresholds}->{$metric}->{critical} = $self->opts->criticalx->{$key};
        last;
      }
    }
  } else {
    $self->{thresholds}->{default}->{warning} =
        defined $self->opts->warning ? $self->opts->warning : defined $params{warning} ? $params{warning} : 0;
    $self->{thresholds}->{default}->{critical} =
        defined $self->opts->critical ? $self->opts->critical : defined $params{critical} ? $params{critical} : 0;
  }
}

sub force_thresholds {
  my ($self, %params) = @_;
  if (exists $params{metric}) {
    my $metric = $params{metric};
    $self->{thresholds}->{$metric}->{warning} = $params{warning} || 0;
    $self->{thresholds}->{$metric}->{critical} = $params{critical} || 0;
  } else {
    $self->{thresholds}->{default}->{warning} = $params{warning} || 0;
    $self->{thresholds}->{default}->{critical} = $params{critical} || 0;
  }
}

sub get_thresholds {
  my ($self, @params) = @_;
  if (scalar(@params) > 1) {
    my %params = @params;
    my $metric = $params{metric};
    return ($self->{thresholds}->{$metric}->{warning},
        $self->{thresholds}->{$metric}->{critical});
  } else {
    return ($self->{thresholds}->{default}->{warning},
        $self->{thresholds}->{default}->{critical});
  }
}

sub check_thresholds {
  my ($self, @params) = @_;
  my $level = $ERRORS{OK};
  my $warningrange;
  my $criticalrange;
  my $value;
  if (scalar(@params) > 1) {
    my %params = @params;
    $value = $params{value};
    my $metric = $params{metric};
    if ($metric ne 'default') {
      $warningrange = exists $self->{thresholds}->{$metric}->{warning} ?
          $self->{thresholds}->{$metric}->{warning} :
          $self->{thresholds}->{default}->{warning};
      $criticalrange = exists $self->{thresholds}->{$metric}->{critical} ?
          $self->{thresholds}->{$metric}->{critical} :
          $self->{thresholds}->{default}->{critical};
    } else {
      $warningrange = (defined $params{warning}) ?
          $params{warning} : $self->{thresholds}->{default}->{warning};
      $criticalrange = (defined $params{critical}) ?
          $params{critical} : $self->{thresholds}->{default}->{critical};
    }
  } else {
    $value = $params[0];
    $warningrange = $self->{thresholds}->{default}->{warning};
    $criticalrange = $self->{thresholds}->{default}->{critical};
  }
  if (! defined $warningrange) {
    # there was no set_thresholds for defaults, no --warning, no --warningx
  } elsif ($warningrange =~ /^([-+]?[0-9]*\.?[0-9]+)$/) {
    # warning = 10, warn if > 10 or < 0
    $level = $ERRORS{WARNING}
        if ($value > $1 || $value < 0);
  } elsif ($warningrange =~ /^([-+]?[0-9]*\.?[0-9]+):$/) {
    # warning = 10:, warn if < 10
    $level = $ERRORS{WARNING}
        if ($value < $1);
  } elsif ($warningrange =~ /^~:([-+]?[0-9]*\.?[0-9]+)$/) {
    # warning = ~:10, warn if > 10
    $level = $ERRORS{WARNING}
        if ($value > $1);
  } elsif ($warningrange =~ /^([-+]?[0-9]*\.?[0-9]+):([-+]?[0-9]*\.?[0-9]+)$/) {
    # warning = 10:20, warn if < 10 or > 20
    $level = $ERRORS{WARNING}
        if ($value < $1 || $value > $2);
  } elsif ($warningrange =~ /^@([-+]?[0-9]*\.?[0-9]+):([-+]?[0-9]*\.?[0-9]+)$/) {
    # warning = @10:20, warn if >= 10 and <= 20
    $level = $ERRORS{WARNING}
        if ($value >= $1 && $value <= $2);
  }
  if (! defined $criticalrange) {
    # there was no set_thresholds for defaults, no --critical, no --criticalx
  } elsif ($criticalrange =~ /^([-+]?[0-9]*\.?[0-9]+)$/) {
    # critical = 10, crit if > 10 or < 0
    $level = $ERRORS{CRITICAL}
        if ($value > $1 || $value < 0);
  } elsif ($criticalrange =~ /^([-+]?[0-9]*\.?[0-9]+):$/) {
    # critical = 10:, crit if < 10
    $level = $ERRORS{CRITICAL}
        if ($value < $1);
  } elsif ($criticalrange =~ /^~:([-+]?[0-9]*\.?[0-9]+)$/) {
    # critical = ~:10, crit if > 10
    $level = $ERRORS{CRITICAL}
        if ($value > $1);
  } elsif ($criticalrange =~ /^([-+]?[0-9]*\.?[0-9]+):([-+]?[0-9]*\.?[0-9]+)$/) {
    # critical = 10:20, crit if < 10 or > 20
    $level = $ERRORS{CRITICAL}
        if ($value < $1 || $value > $2);
  } elsif ($criticalrange =~ /^@([-+]?[0-9]*\.?[0-9]+):([-+]?[0-9]*\.?[0-9]+)$/) {
    # critical = @10:20, crit if >= 10 and <= 20
    $level = $ERRORS{CRITICAL}
        if ($value >= $1 && $value <= $2);
  }
  return $level;
}



package Monitoring::GLPlugin;

=head1 Monitoring::GLPlugin

Monitoring::GLPlugin - infrastructure functions to build a monitoring plugin

=cut

use strict;
use IO::File;
use File::Basename;
use Digest::MD5 qw(md5_hex);
use Errno;
use Data::Dumper;
our $AUTOLOAD;
*VERSION = \'2.1';

use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };

{
  our $mode = undef;
  our $plugin = undef;
  our $pluginname = basename($ENV{'NAGIOS_PLUGIN'} || $0);
  our $blacklist = undef;
  our $info = [];
  our $extendedinfo = [];
  our $summary = [];
  our $variables = {};
}

sub new {
  my ($class, %params) = @_;
  my $self = {};
  bless $self, $class;
  require Monitoring::GLPlugin::Commandline
      if ! grep /BEGIN/, keys %Monitoring::GLPlugin::Commandline::;
  require Monitoring::GLPlugin::Item
      if ! grep /BEGIN/, keys %Monitoring::GLPlugin::Item::;
  require Monitoring::GLPlugin::TableItem
      if ! grep /BEGIN/, keys %Monitoring::GLPlugin::TableItem::;
  $Monitoring::GLPlugin::plugin = Monitoring::GLPlugin::Commandline->new(%params);
  return $self;
}

sub init {
  my ($self) = @_;
  if ($self->opts->can("blacklist") && $self->opts->blacklist &&
      -f $self->opts->blacklist) {
    $self->opts->blacklist = do {
        local (@ARGV, $/) = $self->opts->blacklist; <> };
  }
}

sub dumper {
  my ($self, $object) = @_;
  my $run = $object->{runtime};
  delete $object->{runtime};
  printf STDERR "%s\n", Data::Dumper::Dumper($object);
  $object->{runtime} = $run;
}

sub no_such_mode {
  my ($self) = @_;
  printf "Mode %s is not implemented for this type of device\n",
      $self->opts->mode;
  exit 3;
}

#########################################################
# framework-related. setup, options
#
sub add_default_args {
  my ($self) = @_;
  $self->add_arg(
      spec => 'mode=s',
      help => "--mode
   A keyword which tells the plugin what to do",
      required => 1,
  );
  $self->add_arg(
      spec => 'regexp',
      help => "--regexp
   Parameter name/name2/name3 will be interpreted as (perl) regular expression",
      required => 0,);
  $self->add_arg(
      spec => 'warning=s',
      help => "--warning
   The warning threshold",
      required => 0,);
  $self->add_arg(
      spec => 'critical=s',
      help => "--critical
   The critical threshold",
      required => 0,);
  $self->add_arg(
      spec => 'warningx=s%',
      help => '--warningx
   The extended warning thresholds
   e.g. --warningx db_msdb_free_pct=6: to override the threshold for a
   specific item ',
      required => 0,
  );
  $self->add_arg(
      spec => 'criticalx=s%',
      help => '--criticalx
   The extended critical thresholds',
      required => 0,
  );
  $self->add_arg(
      spec => 'units=s',
      help => "--units
   One of %, B, KB, MB, GB, Bit, KBi, MBi, GBi. (used for e.g. mode interface-usage)",
      required => 0,
  );
  $self->add_arg(
      spec => 'name=s',
      help => "--name
   The name of a specific component to check",
      required => 0,
  );
  $self->add_arg(
      spec => 'name2=s',
      help => "--name2
   The secondary name of a component",
      required => 0,
  );
  $self->add_arg(
      spec => 'name3=s',
      help => "--name3
   The tertiary name of a component",
      required => 0,
  );
  $self->add_arg(
      spec => 'blacklist|b=s',
      help => '--blacklist
   Blacklist some (missing/failed) components',
      required => 0,
      default => '',
  );
  $self->add_arg(
      spec => 'mitigation=s',
      help => "--mitigation
   The parameter allows you to change a critical error to a warning.",
      required => 0,
  );
  $self->add_arg(
      spec => 'lookback=s',
      help => "--lookback
   The amount of time you want to look back when calculating average rates.
   Use it for mode interface-errors or interface-usage. Without --lookback
   the time between two runs of check_nwc_health is the base for calculations.
   If you want your checkresult to be based for example on the past hour,
   use --lookback 3600. ",
      required => 0,
  );
  $self->add_arg(
      spec => 'environment|e=s%',
      help => "--environment
   Add a variable to the plugin's environment",
      required => 0,
  );
  $self->add_arg(
      spec => 'negate=s%',
      help => "--negate
   Emulate the negate plugin. --negate warning=critical --negate unknown=critical",
      required => 0,
  );
  $self->add_arg(
      spec => 'morphmessage=s%',
      help => '--morphmessage
   Modify the final output message',
      required => 0,
  );
  $self->add_arg(
      spec => 'morphperfdata=s%',
      help => "--morphperfdata
   The parameter allows you to change performance data labels.
   It's a perl regexp and a substitution.
   Example: --morphperfdata '(.*)ISATAP(.*)'='\$1patasi\$2'",
      required => 0,
  );
  $self->add_arg(
      spec => 'selectedperfdata=s',
      help => "--selectedperfdata
   The parameter allows you to limit the list of performance data. It's a perl regexp.
   Only matching perfdata show up in the output",
      required => 0,
  );
  $self->add_arg(
      spec => 'report=s',
      help => "--report
   Can be used to shorten the output",
      required => 0,
      default => 'long',
  );
  $self->add_arg(
      spec => 'multiline',
      help => '--multiline
   Multiline output',
      required => 0,
  );
  $self->add_arg(
      spec => 'with-mymodules-dyn-dir=s',
      help => "--with-mymodules-dyn-dir
   Add-on modules for the my-modes will be searched in this directory",
      required => 0,
  );
  $self->add_arg(
      spec => 'statefilesdir=s',
      help => '--statefilesdir
   An alternate directory where the plugin can save files',
      required => 0,
      env => 'STATEFILESDIR',
  );
  $self->add_arg(
      spec => 'isvalidtime=i',
      help => '--isvalidtime
   Signals the plugin to return OK if now is not a valid check time',
      required => 0,
      default => 1,
  );
  $self->add_arg(
      spec => 'reset',
      help => "--reset
   remove the state file",
      aliasfor => "name",
      required => 0,
      hidden => 1,
  );
  $self->add_arg(
      spec => 'drecksptkdb=s',
      help => "--drecksptkdb
   This parameter must be used instead of --name, because Devel::ptkdb is stealing the latter from the command line",
      aliasfor => "name",
      required => 0,
      hidden => 1,
  );
}

sub add_modes {
  my ($self, $modes) = @_;
  my $modestring = "";
  my @modes = @{$modes};
  my $longest = length ((reverse sort {length $a <=> length $b} map { $_->[1] } @modes)[0]);
  my $format = "       %-".
      (length ((reverse sort {length $a <=> length $b} map { $_->[1] } @modes)[0])).
      "s\t(%s)\n";
  foreach (@modes) {
    $modestring .= sprintf $format, $_->[1], $_->[3];
  }
  $modestring .= sprintf "\n";
  $Monitoring::GLPlugin::plugin->{modestring} = $modestring;
}

sub add_arg {
  my ($self, %args) = @_;
  if ($args{help} =~ /^--mode/) {
    $args{help} .= "\n".$Monitoring::GLPlugin::plugin->{modestring};
  }
  $Monitoring::GLPlugin::plugin->{opts}->add_arg(%args);
}

sub mod_arg {
  my ($self, @arg) = @_;
  $Monitoring::GLPlugin::plugin->{opts}->mod_arg(@arg);
}

sub add_mode {
  my ($self, %args) = @_;
  push(@{$Monitoring::GLPlugin::plugin->{modes}}, \%args);
  my $longest = length ((reverse sort {length $a <=> length $b} map { $_->{spec} } @{$Monitoring::GLPlugin::plugin->{modes}})[0]);
  my $format = "       %-".
      (length ((reverse sort {length $a <=> length $b} map { $_->{spec} } @{$Monitoring::GLPlugin::plugin->{modes}})[0])).
      "s\t(%s)\n";
  $Monitoring::GLPlugin::plugin->{modestring} = "";
  foreach (@{$Monitoring::GLPlugin::plugin->{modes}}) {
    $Monitoring::GLPlugin::plugin->{modestring} .= sprintf $format, $_->{spec}, $_->{help};
  }
  $Monitoring::GLPlugin::plugin->{modestring} .= "\n";
}

sub validate_args {
  my ($self) = @_;
  if ($self->opts->mode =~ /^my-([^\-.]+)/) {
    my $param = $self->opts->mode;
    $param =~ s/\-/::/g;
    $self->add_mode(
        internal => $param,
        spec => $self->opts->mode,
        alias => undef,
        help => 'my extension',
    );
  } elsif ($self->opts->mode eq 'encode') {
    my $input = <>;
    chomp $input;
    $input =~ s/([^A-Za-z0-9])/sprintf("%%%02X", ord($1))/seg;
    printf "%s\n", $input;
    exit 0;
  } elsif ($self->opts->mode eq 'decode') {
    if (! -t STDIN) {
      my $input = <>;
      chomp $input;
      $input =~ s/%([A-Za-z0-9]{2})/chr(hex($1))/seg;
      printf "%s\n", $input;
      exit OK;
    } else {
      if ($self->opts->name) {
        my $input = $self->opts->name;
        $input =~ s/%([A-Za-z0-9]{2})/chr(hex($1))/seg;
        printf "%s\n", $input;
        exit OK;
      } else {
        printf "i can't find your encoded statement. use --name or pipe it in my stdin\n";
        exit UNKNOWN;
      }
    }
  } elsif ((! grep { $self->opts->mode eq $_ } map { $_->{spec} } @{$Monitoring::GLPlugin::plugin->{modes}}) &&
      (! grep { $self->opts->mode eq $_ } map { defined $_->{alias} ? @{$_->{alias}} : () } @{$Monitoring::GLPlugin::plugin->{modes}})) {
    printf "UNKNOWN - mode %s\n", $self->opts->mode;
    $self->opts->print_help();
    exit 3;
  }
  if ($self->opts->name && $self->opts->name =~ /(%22)|(%27)/) {
    my $name = $self->opts->name;
    $name =~ s/\%([A-Fa-f0-9]{2})/pack('C', hex($1))/seg;
    $self->override_opt('name', $name);
  }
  $Monitoring::GLPlugin::mode = (
      map { $_->{internal} }
      grep {
         ($self->opts->mode eq $_->{spec}) ||
         ( defined $_->{alias} && grep { $self->opts->mode eq $_ } @{$_->{alias}})
      } @{$Monitoring::GLPlugin::plugin->{modes}}
  )[0];
  if ($self->opts->multiline) {
    $ENV{NRPE_MULTILINESUPPORT} = 1;
  } else {
    $ENV{NRPE_MULTILINESUPPORT} = 0;
  }
  if ($self->opts->can("statefilesdir") && ! $self->opts->statefilesdir) {
    if ($^O =~ /MSWin/) {
      if (defined $ENV{TEMP}) {
        $self->override_opt('statefilesdir', $ENV{TEMP}."/".$Monitoring::GLPlugin::plugin->{name});
      } elsif (defined $ENV{TMP}) {
        $self->override_opt('statefilesdir', $ENV{TMP}."/".$Monitoring::GLPlugin::plugin->{name});
      } elsif (defined $ENV{windir}) {
        $self->override_opt('statefilesdir', File::Spec->catfile($ENV{windir}, 'Temp')."/".$Monitoring::GLPlugin::plugin->{name});
      } else {
        $self->override_opt('statefilesdir', "C:/".$Monitoring::GLPlugin::plugin->{name});
      }
    } elsif (exists $ENV{OMD_ROOT}) {
      $self->override_opt('statefilesdir', $ENV{OMD_ROOT}."/var/tmp/".$Monitoring::GLPlugin::plugin->{name});
    } else {
      $self->override_opt('statefilesdir', "/var/tmp/".$Monitoring::GLPlugin::plugin->{name});
    }
  }
  $Monitoring::GLPlugin::plugin->{statefilesdir} = $self->opts->statefilesdir
      if $self->opts->can("statefilesdir");
  if ($self->opts->can("warningx") && $self->opts->warningx) {
    foreach my $key (keys %{$self->opts->warningx}) {
      $self->set_thresholds(metric => $key,
          warning => $self->opts->warningx->{$key});
    }
  }
  if ($self->opts->can("criticalx") && $self->opts->criticalx) {
    foreach my $key (keys %{$self->opts->criticalx}) {
      $self->set_thresholds(metric => $key,
          critical => $self->opts->criticalx->{$key});
    }
  }
  $self->set_timeout_alarm() if ! $SIG{'ALRM'};
}

sub set_timeout_alarm {
  my ($self, $timeout, $handler) = @_;
  $timeout ||= $self->opts->timeout;
  $handler ||= sub {
    printf "UNKNOWN - %s timed out after %d seconds\n",
        $Monitoring::GLPlugin::plugin->{name}, $self->opts->timeout;
    exit 3;
  };
  use POSIX ':signal_h';
  if ($^O =~ /MSWin/) {
    local $SIG{'ALRM'} = $handler;
  } else {
    my $mask = POSIX::SigSet->new( SIGALRM );
    my $action = POSIX::SigAction->new(
        $handler, $mask
    );   
    my $oldaction = POSIX::SigAction->new();
    sigaction(SIGALRM ,$action ,$oldaction );
  }    
  alarm(int($timeout)); # 1 second before the global unknown timeout
}

#########################################################
# global helpers
#
sub set_variable {
  my ($self, $key, $value) = @_;
  $Monitoring::GLPlugin::variables->{$key} = $value;
}

sub get_variable {
  my ($self, $key, $fallback) = @_;
  return exists $Monitoring::GLPlugin::variables->{$key} ?
      $Monitoring::GLPlugin::variables->{$key} : $fallback;
}

sub debug {
  my ($self, $format, @message) = @_;
  my $tracefile = "/tmp/".$Monitoring::GLPlugin::pluginname.".trace";
  $self->{trace} = -f $tracefile ? 1 : 0;
  if ($self->get_variable("verbose") &&
      $self->get_variable("verbose") > $self->get_variable("verbosity", 10)) {
    printf("%s: ", scalar localtime);
    printf($format, @message);
    printf "\n";
  }
  if ($self->{trace}) {
    my $logfh = IO::File->new();
    $logfh->autoflush(1);
    if ($logfh->open($tracefile, "a")) {
      $logfh->printf("%s: ", scalar localtime);
      $logfh->printf($format, @message);
      $logfh->printf("\n");
      $logfh->close();
    }
  }
}

sub filter_namex {
  my ($self, $opt, $name) = @_;
  if ($opt) {
    if ($self->opts->regexp) {
      if ($name =~ /$opt/i) {
        return 1;
      }
    } else {
      if (lc $opt eq lc $name) {
        return 1;
      }
    }
  } else {
    return 1;
  }
  return 0;
}

sub filter_name {
  my ($self, $name) = @_;
  return $self->filter_namex($self->opts->name, $name);
}

sub filter_name2 {
  my ($self, $name) = @_;
  return $self->filter_namex($self->opts->name2, $name);
}

sub filter_name3 {
  my ($self, $name) = @_;
  return $self->filter_namex($self->opts->name3, $name);
}

sub version_is_minimum {
  my ($self, $version) = @_;
  my $installed_version;
  my $newer = 1;
  if ($self->get_variable("version")) {
    $installed_version = $self->get_variable("version");
  } elsif (exists $self->{version}) {
    $installed_version = $self->{version};
  } else {
    return 0;
  }
  my @v1 = map { $_ eq "x" ? 0 : $_ } split(/\./, $version);
  my @v2 = split(/\./, $installed_version);
  if (scalar(@v1) > scalar(@v2)) {
    push(@v2, (0) x (scalar(@v1) - scalar(@v2)));
  } elsif (scalar(@v2) > scalar(@v1)) {
    push(@v1, (0) x (scalar(@v2) - scalar(@v1)));
  }
  foreach my $pos (0..$#v1) {
    if ($v2[$pos] > $v1[$pos]) {
      $newer = 1;
      last;
    } elsif ($v2[$pos] < $v1[$pos]) {
      $newer = 0;
      last;
    }
  }
  return $newer;
}

sub accentfree {
  my ($self, $text) = @_;
  # thanks mycoyne who posted this accent-remove-algorithm
  # http://www.experts-exchange.com/Programming/Languages/Scripting/Perl/Q_23275533.html#a21234612
  my @transformed;
  my %replace = (
    '9a' => 's', '9c' => 'oe', '9e' => 'z', '9f' => 'Y', 'c0' => 'A', 'c1' => 'A',
    'c2' => 'A', 'c3' => 'A', 'c4' => 'A', 'c5' => 'A', 'c6' => 'AE', 'c7' => 'C',
    'c8' => 'E', 'c9' => 'E', 'ca' => 'E', 'cb' => 'E', 'cc' => 'I', 'cd' => 'I',
    'ce' => 'I', 'cf' => 'I', 'd0' => 'D', 'd1' => 'N', 'd2' => 'O', 'd3' => 'O',
    'd4' => 'O', 'd5' => 'O', 'd6' => 'O', 'd8' => 'O', 'd9' => 'U', 'da' => 'U',
    'db' => 'U', 'dc' => 'U', 'dd' => 'Y', 'e0' => 'a', 'e1' => 'a', 'e2' => 'a',
    'e3' => 'a', 'e4' => 'a', 'e5' => 'a', 'e6' => 'ae', 'e7' => 'c', 'e8' => 'e',
    'e9' => 'e', 'ea' => 'e', 'eb' => 'e', 'ec' => 'i', 'ed' => 'i', 'ee' => 'i',
    'ef' => 'i', 'f0' => 'o', 'f1' => 'n', 'f2' => 'o', 'f3' => 'o', 'f4' => 'o',
    'f5' => 'o', 'f6' => 'o', 'f8' => 'o', 'f9' => 'u', 'fa' => 'u', 'fb' => 'u',
    'fc' => 'u', 'fd' => 'y', 'ff' => 'y',
  );
  my @letters = split //, $text;;
  for (my $i = 0; $i <= $#letters; $i++) {
    my $hex = sprintf "%x", ord($letters[$i]);
    $letters[$i] = $replace{$hex} if (exists $replace{$hex});
  }
  push @transformed, @letters;
  return join '', @transformed;
}

sub dump {
  my ($self) = @_;
  my $class = ref($self);
  $class =~ s/^.*:://;
  if (exists $self->{flat_indices}) {
    printf "[%s_%s]\n", uc $class, $self->{flat_indices};
  } else {
    printf "[%s]\n", uc $class;
  }
  foreach (grep !/^(info|trace|warning|critical|blacklisted|extendedinfo|flat_indices|indices)$/, sort keys %{$self}) {
    printf "%s: %s\n", $_, $self->{$_} if defined $self->{$_} && ref($self->{$_}) ne "ARRAY";
  }
  if ($self->{info}) {
    printf "info: %s\n", $self->{info};
  }
  printf "\n";
  foreach (grep !/^(info|trace|warning|critical|blacklisted|extendedinfo|flat_indices|indices)$/, sort keys %{$self}) {
    if (defined $self->{$_} && ref($self->{$_}) eq "ARRAY") {
      my $have_flat_indices = 1;
      foreach my $obj (@{$self->{$_}}) {
        $have_flat_indices = 0 if (ref($obj) ne "HASH" || ! exists $obj->{flat_indices});
      }
      if ($have_flat_indices) {
        foreach my $obj (sort {
            join('', map { sprintf("%30d",$_) } split( /\./, $a->{flat_indices})) cmp
            join('', map { sprintf("%30d",$_) } split( /\./, $b->{flat_indices}))
        } @{$self->{$_}}) {
          $obj->dump();
        }
      } else {
        foreach my $obj (@{$self->{$_}}) {
          $obj->dump() if UNIVERSAL::can($obj, "isa") && $obj->can("dump");
        }
      }
    }
  }
}

sub table_ascii {
  my ($self, $table, $titles) = @_;
  my $text = "";
  my $column_length = {};
  my $column = 0;
  foreach (@{$titles}) {
    $column_length->{$column++} = length($_);
  }
  foreach my $tr (@{$table}) {
    @{$tr} = map { ref($_) eq "ARRAY" ? $_->[0] : $_; } @{$tr};
    $column = 0;
    foreach my $td (@{$tr}) {
      if (length($td) > $column_length->{$column}) {
        $column_length->{$column} = length($td);
      }
      $column++;
    }
  }
  $column = 0;
  foreach (@{$titles}) {
    $column_length->{$column} = "%".($column_length->{$column} + 3)."s";
    $column++;
  }
  $column = 0;
  foreach (@{$titles}) {
    $text .= sprintf $column_length->{$column++}, $_;
  }
  $text .= "\n";
  foreach my $tr (@{$table}) {
    $column = 0;
    foreach my $td (@{$tr}) {
      $text .= sprintf $column_length->{$column++}, $td;
    }
    $text .= "\n";
  }
  return $text;
}

sub table_html {
  my ($self, $table, $titles) = @_;
  my $text = "";
  $text .= "<table style=\"border-collapse:collapse; border: 1px solid black;\">";
  $text .= "<tr>";
  foreach (@{$titles}) {
    $text .= sprintf "<th style=\"text-align: left; padding-left: 4px; padding-right: 6px;\">%s</th>", $_;
  }
  $text .= "</tr>";
  foreach my $tr (@{$table}) {
    $text .= "<tr>";
    foreach my $td (@{$tr}) {
      my $class = "statusOK";
      if (ref($td) eq "ARRAY") {
        $class = {
          0 => "statusOK",
          1 => "statusWARNING",
          2 => "statusCRITICAL",
          3 => "statusUNKNOWN",
        }->{$td->[1]};
        $td = $td->[0];
      }
      $text .= sprintf "<td style=\"text-align: left; padding-left: 4px; padding-right: 6px;\" class=\"%s\">%s</td>", $class, $td;
    }
    $text .= "</tr>";
  }
  $text .= "</table>";
  return $text;
}

sub load_my_extension {
  my ($self) = @_;
  if ($self->opts->mode =~ /^my-([^-.]+)/) {
    my $class = $1;
    my $loaderror = undef;
    substr($class, 0, 1) = uc substr($class, 0, 1);
    if (! $self->opts->get("with-mymodules-dyn-dir")) {
      $self->override_opt("with-mymodules-dyn-dir", "");
    }
    my $plugin_name = $Monitoring::GLPlugin::pluginname;
    $plugin_name =~ /check_(.*?)_health/;
    $plugin_name = "Check".uc(substr($1, 0, 1)).substr($1, 1)."Health";
    foreach my $libpath (split(":", $self->opts->get("with-mymodules-dyn-dir"))) {
      foreach my $extmod (glob $libpath."/".$plugin_name."*.pm") {
        my $stderrvar;
        *SAVEERR = *STDERR;
        open OUT ,'>',\$stderrvar;
        *STDERR = *OUT;
        eval {
          $self->debug(sprintf "loading module %s", $extmod);
          require $extmod;
        };
        *STDERR = *SAVEERR;
        if ($@) {
          $loaderror = $extmod;
          $self->debug(sprintf "failed loading module %s: %s", $extmod, $@);
        }
      }
    }
    my $original_class = ref($self);
    my $original_init = $self->can("init");
    $self->compatibility_class() if $self->can('compatibility_class');
    bless $self, "My$class";
    $self->compatibility_methods() if $self->can('compatibility_methods');
    if ($self->isa("Monitoring::GLPlugin")) {
      my $new_init = $self->can("init");
      if ($new_init == $original_init) {
          $self->add_unknown(
              sprintf "Class %s needs an init() method", ref($self));
      } else {
        # now go back to check_*_health.pl where init() will be called
      }
    } else {
      bless $self, $original_class;
      $self->add_unknown(
          sprintf "Class %s is not a subclass of Monitoring::GLPlugin%s",
              "My$class",
              $loaderror ? sprintf " (syntax error in %s?)", $loaderror : "" );
      my ($code, $message) = $self->check_messages(join => ', ', join_all => ', ');
      $self->nagios_exit($code, $message);
    }
  }
}

sub decode_password {
  my ($self, $password) = @_;
  if ($password && $password =~ /^rfc3986:\/\/(.*)/) {
    $password = $1;
    $password =~ s/%([A-Za-z0-9]{2})/chr(hex($1))/seg;
  }
  return $password;
}

sub number_of_bits {
  my ($self, $unit) = @_;
  # https://en.wikipedia.org/wiki/Data_rate_units
  my $bits = {
    'bit' => 1,			# Bit per second
    'B' => 8,			# Byte per second, 8 bits per second
    'kbit' => 1000,		# Kilobit per second, 1,000 bits per second
    'kb' => 1000,		# Kilobit per second, 1,000 bits per second
    'Kibit' => 1024,		# Kibibit per second, 1,024 bits per second
    'kB' => 8000,		# Kilobyte per second, 8,000 bits per second
    'KiB' => 8192,		# Kibibyte per second, 1,024 bytes per second
    'Mbit' => 1000000,		# Megabit per second, 1,000,000 bits per second
    'Mb' => 1000000,		# Megabit per second, 1,000,000 bits per second
    'Mibit' => 1048576,		# Mebibit per second, 1,024 kibibits per second
    'MB' => 8000000,		# Megabyte per second, 1,000 kilobytes per second
    'MiB' => 8388608,		# Mebibyte per second, 1,024 kibibytes per second
    'Gbit' => 1000000000,	# Gigabit per second, 1,000 megabits per second
    'Gb' => 1000000000,		# Gigabit per second, 1,000 megabits per second
    'Gibit' => 1073741824,	# Gibibit per second, 1,024 mebibits per second
    'GB' => 8000000000,		# Gigabyte per second, 1,000 megabytes per second
    'GiB' => 8589934592,	# Gibibyte per second, 8192 mebibits per second
    'Tbit' => 1000000000000,	# Terabit per second, 1,000 gigabits per second
    'Tb' => 1000000000000,	# Terabit per second, 1,000 gigabits per second
    'Tibit' => 1099511627776,	# Tebibit per second, 1,024 gibibits per second
    'TB' => 8000000000000,	# Terabyte per second, 1,000 gigabytes per second
    # eigene kreationen
    'Bits' => 1,
    'Bit' => 1,			# Bit per second
    'KB' => 1024,		# Kilobyte (like disk kilobyte)
    'KBi' => 1024,		# -"-
    'MBi' => 1024 * 1024,	# Megabyte (like disk megabyte)
    'GBi' => 1024 * 1024 * 1024, # Gigybate (like disk gigybyte)
  };
  if (exists $bits->{$unit}) {
    return $bits->{$unit};
  } else {
    return 0;
  }
}


#########################################################
# runtime methods
#
sub mode : lvalue {
  my ($self) = @_;
  $Monitoring::GLPlugin::mode;
}

sub statefilesdir {
  my ($self) = @_;
  return $Monitoring::GLPlugin::plugin->{statefilesdir};
}

sub opts { # die beiden _nicht_ in AUTOLOAD schieben, das kracht!
  my ($self) = @_;
  return $Monitoring::GLPlugin::plugin->opts();
}

sub getopts {
  my ($self, $envparams) = @_;
  $envparams ||= [];
  $Monitoring::GLPlugin::plugin->getopts();
  # es kann sein, dass beim aufraeumen zum schluss als erstes objekt
  # das $Monitoring::GLPlugin::plugin geloescht wird. in anderen destruktoren
  # (insb. fuer dbi disconnect) steht dann $self->opts->verbose
  # nicht mehr zur verfuegung bzw. $Monitoring::GLPlugin::plugin->opts ist undef.
  $self->set_variable("verbose", $self->opts->verbose);
  #
  # die gueltigkeit von modes wird bereits hier geprueft und nicht danach
  # in validate_args. (zwischen getopts und validate_args wird
  # normalerweise classify aufgerufen, welches bereits eine verbindung
  # zum endgeraet herstellt. bei falschem mode waere das eine verschwendung
  # bzw. durch den exit3 ein evt. unsauberes beenden der verbindung.
  if ((! grep { $self->opts->mode eq $_ } map { $_->{spec} } @{$Monitoring::GLPlugin::plugin->{modes}}) &&
      (! grep { $self->opts->mode eq $_ } map { defined $_->{alias} ? @{$_->{alias}} : () } @{$Monitoring::GLPlugin::plugin->{modes}})) {
    if ($self->opts->mode !~ /^my-/) {
      printf "UNKNOWN - mode %s\n", $self->opts->mode;
      $self->opts->print_help();
      exit 3;
    }
  }
}

sub add_ok {
  my ($self, $message) = @_;
  $message ||= $self->{info};
  $self->add_message(OK, $message);
}

sub add_warning {
  my ($self, $message) = @_;
  $message ||= $self->{info};
  $self->add_message(WARNING, $message);
}

sub add_critical {
  my ($self, $message) = @_;
  $message ||= $self->{info};
  $self->add_message(CRITICAL, $message);
}

sub add_unknown {
  my ($self, $message) = @_;
  $message ||= $self->{info};
  $self->add_message(UNKNOWN, $message);
}

sub add_ok_mitigation {
  my ($self, $message) = @_;
  if (defined $self->opts->mitigation()) {
    $self->add_message($self->opts->mitigation(), $message);
  } else {
    $self->add_ok($message);
  }
}

sub add_warning_mitigation {
  my ($self, $message) = @_;
  if (defined $self->opts->mitigation()) {
    $self->add_message($self->opts->mitigation(), $message);
  } else {
    $self->add_warning($message);
  }
}

sub add_critical_mitigation {
  my ($self, $message) = @_;
  if (defined $self->opts->mitigation()) {
    $self->add_message($self->opts->mitigation(), $message);
  } else {
    $self->add_critical($message);
  }
}

sub add_unknown_mitigation {
  my ($self, $message) = @_;
  if (defined $self->opts->mitigation()) {
    $self->add_message($self->opts->mitigation(), $message);
  } else {
    $self->add_unknown($message);
  }
}

sub add_message {
  my ($self, $level, $message) = @_;
  $message ||= $self->{info};
  $Monitoring::GLPlugin::plugin->add_message($level, $message)
      unless $self->is_blacklisted();
  if (exists $self->{failed}) {
    if ($level == UNKNOWN && $self->{failed} == OK) {
      $self->{failed} = $level;
    } elsif ($level > $self->{failed}) {
      $self->{failed} = $level;
    }
  }
}

sub clear_ok {
  my ($self) = @_;
  $self->clear_messages(OK);
}

sub clear_warning {
  my ($self) = @_;
  $self->clear_messages(WARNING);
}

sub clear_critical {
  my ($self) = @_;
  $self->clear_messages(CRITICAL);
}

sub clear_unknown {
  my ($self) = @_;
  $self->clear_messages(UNKNOWN);
}

sub clear_all { # deprecated, use clear_messages
  my ($self) = @_;
  $self->clear_ok();
  $self->clear_warning();
  $self->clear_critical();
  $self->clear_unknown();
}

sub set_level {
  my ($self, $code) = @_;
  $code = (qw(ok warning critical unknown))[$code] if $code =~ /^\d+$/;
  $code = lc $code;
  if (! exists $self->{tmp_level}) {
    $self->{tmp_level} = {
      ok => 0,
      warning => 0,
      critical => 0,
      unknown => 0,
    };
  }
  $self->{tmp_level}->{$code}++;
}

sub get_level {
  my ($self) = @_;
  return OK if ! exists $self->{tmp_level};
  my $code = OK;
  $code ||= CRITICAL if $self->{tmp_level}->{critical};
  $code ||= WARNING  if $self->{tmp_level}->{warning};
  $code ||= UNKNOWN  if $self->{tmp_level}->{unknown};
  return $code;
}

#########################################################
# blacklisting
#
sub blacklist {
  my ($self) = @_;
  $self->{blacklisted} = 1;
}

sub add_blacklist {
  my ($self, $list) = @_;
  $Monitoring::GLPlugin::blacklist = join('/',
      (split('/', $self->opts->blacklist), $list));
}

sub is_blacklisted {
  my ($self) = @_;
  if (! $self->opts->can("blacklist")) {
    return 0;
  }
  if (! exists $self->{blacklisted}) {
    $self->{blacklisted} = 0;
  }
  if (exists $self->{blacklisted} && $self->{blacklisted}) {
    return $self->{blacklisted};
  }
  # FAN:459,203/TEMP:102229/ENVSUBSYSTEM
  # FAN_459,FAN_203,TEMP_102229,ENVSUBSYSTEM
  if ($self->opts->blacklist =~ /_/) {
    foreach my $bl_item (split(/,/, $self->opts->blacklist)) {
      if ($bl_item eq $self->internal_name()) {
        $self->{blacklisted} = 1;
      }
    }
  } else {
    foreach my $bl_items (split(/\//, $self->opts->blacklist)) {
      if ($bl_items =~ /^(\w+):([\:\d\-,]+)$/) {
        my $bl_type = $1;
        my $bl_names = $2;
        foreach my $bl_name (split(/,/, $bl_names)) {
          if ($bl_type."_".$bl_name eq $self->internal_name()) {
            $self->{blacklisted} = 1;
          }
        }
      } elsif ($bl_items =~ /^(\w+)$/) {
        if ($bl_items eq $self->internal_name()) {
          $self->{blacklisted} = 1;
        }
      }
    }
  }
  return $self->{blacklisted};
}

#########################################################
# additional info
#
sub add_info {
  my ($self, $info) = @_;
  $info = $self->is_blacklisted() ? $info.' (blacklisted)' : $info;
  $self->{info} = $info;
  push(@{$Monitoring::GLPlugin::info}, $info);
}

sub annotate_info {
  my ($self, $annotation) = @_;
  my $lastinfo = pop(@{$Monitoring::GLPlugin::info});
  $lastinfo .= sprintf ' (%s)', $annotation;
  $self->{info} = $lastinfo;
  push(@{$Monitoring::GLPlugin::info}, $lastinfo);
}

sub add_extendedinfo {  # deprecated
  my ($self, $info) = @_;
  $self->{extendedinfo} = $info;
  return if ! $self->opts->extendedinfo;
  push(@{$Monitoring::GLPlugin::extendedinfo}, $info);
}

sub get_info {
  my ($self, $separator) = @_;
  $separator ||= ' ';
  return join($separator , @{$Monitoring::GLPlugin::info});
}

sub get_last_info {
  my ($self) = @_;
  return pop(@{$Monitoring::GLPlugin::info});
}

sub get_extendedinfo {
  my ($self, $separator) = @_;
  $separator ||= ' ';
  return join($separator, @{$Monitoring::GLPlugin::extendedinfo});
}

sub add_summary {  # deprecated
  my ($self, $summary) = @_;
  push(@{$Monitoring::GLPlugin::summary}, $summary);
}

sub get_summary {
  my ($self) = @_;
  return join(', ', @{$Monitoring::GLPlugin::summary});
}

#########################################################
# persistency
#
sub valdiff {
  my ($self, $pparams, @keys) = @_;
  my %params = %{$pparams};
  my $now = time;
  my $newest_history_set = {};
  $params{freeze} = 0 if ! $params{freeze};
  my $mode = "normal";
  if ($self->opts->lookback && $self->opts->lookback == 99999 && $params{freeze} == 0) {
    $mode = "lookback_freeze_chill";
  } elsif ($self->opts->lookback && $self->opts->lookback == 99999 && $params{freeze} == 1) {
    $mode = "lookback_freeze_shockfrost";
  } elsif ($self->opts->lookback && $self->opts->lookback == 99999 && $params{freeze} == 2) {
    $mode = "lookback_freeze_defrost";
  } elsif ($self->opts->lookback) {
    $mode = "lookback";
  }
  # lookback=99999, freeze=0(default)
  #  nimm den letzten lauf und schreib ihn nach {cold}
  #  vergleich dann
  #    wenn es frozen gibt, vergleich frozen und den letzten lauf
  #    sonst den letzten lauf und den aktuellen lauf
  # lookback=99999, freeze=1
  #  wird dann aufgerufen,wenn nach dem freeze=0 ein problem festgestellt wurde
  #     (also als 2.valdiff hinterher)
  #  schreib cold nach frozen
  # lookback=99999, freeze=2
  #  wird dann aufgerufen,wenn nach dem freeze=0 wieder alles ok ist
  #     (also als 2.valdiff hinterher)
  #  loescht frozen
  #
  my $last_values = $self->load_state(%params) || eval {
    my $empty_events = {};
    foreach (@keys) {
      if (ref($self->{$_}) eq "ARRAY") {
        $empty_events->{$_} = [];
      } else {
        $empty_events->{$_} = 0;
      }
    }
    $empty_events->{timestamp} = 0;
    if ($mode eq "lookback") {
      $empty_events->{lookback_history} = {};
    } elsif ($mode eq "lookback_freeze_chill") {
      $empty_events->{cold} = {};
      $empty_events->{frozen} = {};
    }
    $empty_events;
  };
  $self->{'delta_timestamp'} = $now - $last_values->{timestamp};
  foreach (@keys) {
    if ($mode eq "lookback_freeze_chill") {
      # die werte vom letzten lauf wegsichern.
      # vielleicht gibts gleich einen freeze=1, dann muessen die eingefroren werden
      if (exists $last_values->{$_}) {
        if (ref($self->{$_}) eq "ARRAY") {
          $last_values->{cold}->{$_} = [];
          foreach my $value (@{$last_values->{$_}}) {
            push(@{$last_values->{cold}->{$_}}, $value);
          }
        } else {
          $last_values->{cold}->{$_} = $last_values->{$_};
        }
      } else {
        if (ref($self->{$_}) eq "ARRAY") {
          $last_values->{cold}->{$_} = [];
        } else {
          $last_values->{cold}->{$_} = 0;
        }
      }
      # es wird so getan, als sei der frozen wert vom letzten lauf
      if (exists $last_values->{frozen}->{$_}) {
        if (ref($self->{$_}) eq "ARRAY") {
          $last_values->{$_} = [];
          foreach my $value (@{$last_values->{frozen}->{$_}}) {
            push(@{$last_values->{$_}}, $value);
          }
        } else {
          $last_values->{$_} = $last_values->{frozen}->{$_};
        }
      }
    } elsif ($mode eq "lookback") {
      # find a last_value in the history which fits lookback best
      # and overwrite $last_values->{$_} with historic data
      if (exists $last_values->{lookback_history}->{$_}) {
        foreach my $date (sort {$a <=> $b} keys %{$last_values->{lookback_history}->{$_}}) {
            $newest_history_set->{$_} = $last_values->{lookback_history}->{$_}->{$date};
            $newest_history_set->{timestamp} = $date;
        }
        foreach my $date (sort {$a <=> $b} keys %{$last_values->{lookback_history}->{$_}}) {
          if ($date >= ($now - $self->opts->lookback)) {
            $last_values->{$_} = $last_values->{lookback_history}->{$_}->{$date};
            $last_values->{timestamp} = $date;
            if (ref($last_values->{$_}) eq "ARRAY") {
              $self->debug(sprintf "oldest value of %s within lookback is size %s (age %d)",
                  $_, scalar(@{$last_values->{$_}}), time - $date);
            } else {
              $self->debug(sprintf "oldest value of %s within lookback is %s (age %d)",
                  $_, $last_values->{$_}, time - $date);
            }
            last;
          } else {
            $self->debug(sprintf "deprecate %s of age %d", $_, time - $date);
            delete $last_values->{lookback_history}->{$_}->{$date};
          }
        }
      }
    }
    if ($mode eq "normal" || $mode eq "lookback" || $mode eq "lookback_freeze_chill") {
      if ($self->{$_} =~ /^\d+\.*\d*$/) {
        $last_values->{$_} = 0 if ! exists $last_values->{$_};
        if ($self->{$_} >= $last_values->{$_}) {
          $self->{'delta_'.$_} = $self->{$_} - $last_values->{$_};
        } elsif ($self->{$_} eq $last_values->{$_}) {
          # dawischt! in einem fall wurde 131071.999023438 >= 131071.999023438 da oben nicht erkannt
          # subtrahieren ging auch daneben, weil ein winziger negativer wert rauskam.
          $self->{'delta_'.$_} = 0;
        } else {
          if ($mode =~ /lookback_freeze/) {
            # hier koennen delta-werte auch negativ sein, wenn z.b. peers verschwinden
            $self->{'delta_'.$_} = $self->{$_} - $last_values->{$_};
          } elsif (exists $params{lastarray}) {
            $self->{'delta_'.$_} = $self->{$_} - $last_values->{$_};
          } else {
            # vermutlich db restart und zaehler alle auf null
            $self->{'delta_'.$_} = $self->{$_};
          }
        }
        $self->debug(sprintf "delta_%s %f", $_, $self->{'delta_'.$_});
        $self->{$_.'_per_sec'} = $self->{'delta_timestamp'} ?
            $self->{'delta_'.$_} / $self->{'delta_timestamp'} : 0;
      } elsif (ref($self->{$_}) eq "ARRAY") {
        if ((! exists $last_values->{$_} || ! defined $last_values->{$_}) && exists $params{lastarray}) {
          # innerhalb der lookback-zeit wurde nichts in der lookback_history
          # gefunden. allenfalls irgendwas aelteres. normalerweise
          # wuerde jetzt das array als [] initialisiert.
          # d.h. es wuerde ein delta geben, @found s.u.
          # wenn man das nicht will, sondern einfach aktuelles array mit
          # dem array des letzten laufs vergleichen will, setzt man lastarray
          $last_values->{$_} = %{$newest_history_set} ?
              $newest_history_set->{$_} : []
        } elsif ((! exists $last_values->{$_} || ! defined $last_values->{$_}) && ! exists $params{lastarray}) {
          $last_values->{$_} = [] if ! exists $last_values->{$_};
        } elsif (exists $last_values->{$_} && ! defined $last_values->{$_}) {
          # $_ kann es auch ausserhalb des lookback_history-keys als normalen
          # key geben. der zeigt normalerweise auf den entspr. letzten
          # lookback_history eintrag. wurde der wegen ueberalterung abgeschnitten
          # ist der hier auch undef.
          $last_values->{$_} = %{$newest_history_set} ?
              $newest_history_set->{$_} : []
        }
        my %saved = map { $_ => 1 } @{$last_values->{$_}};
        my %current = map { $_ => 1 } @{$self->{$_}};
        my @found = grep(!defined $saved{$_}, @{$self->{$_}});
        my @lost = grep(!defined $current{$_}, @{$last_values->{$_}});
        $self->{'delta_found_'.$_} = \@found;
        $self->{'delta_lost_'.$_} = \@lost;
      }
    }
  }
  $params{save} = eval {
    my $empty_events = {};
    foreach (@keys) {
      $empty_events->{$_} = $self->{$_};
      if ($mode =~ /lookback_freeze/) {
        if (exists $last_values->{frozen}->{$_}) {
          if (ref($last_values->{frozen}->{$_}) eq "ARRAY") {
            @{$empty_events->{cold}->{$_}} = @{$last_values->{frozen}->{$_}};
          } else {
            $empty_events->{cold}->{$_} = $last_values->{frozen}->{$_};
          }
        } else {
          if (ref($last_values->{cold}->{$_}) eq "ARRAY") {
            @{$empty_events->{cold}->{$_}} = @{$last_values->{cold}->{$_}};
          } else {
            $empty_events->{cold}->{$_} = $last_values->{cold}->{$_};
          }
        }
        $empty_events->{cold}->{timestamp} = $last_values->{cold}->{timestamp};
      }
      if ($mode eq "lookback_freeze_shockfrost") {
        if (ref($empty_events->{cold}->{$_}) eq "ARRAY") {
          @{$empty_events->{frozen}->{$_}} = @{$empty_events->{cold}->{$_}};
        } else {
          $empty_events->{frozen}->{$_} = $empty_events->{cold}->{$_};
        }
        $empty_events->{frozen}->{timestamp} = $now;
      }
    }
    $empty_events->{timestamp} = $now;
    if ($mode eq "lookback") {
      $empty_events->{lookback_history} = $last_values->{lookback_history};
      foreach (@keys) {
        if (ref($self->{$_}) eq "ARRAY") {
          @{$empty_events->{lookback_history}->{$_}->{$now}} = @{$self->{$_}};
        } else {
          $empty_events->{lookback_history}->{$_}->{$now} = $self->{$_};
        }
      }
    }
    if ($mode eq "lookback_freeze_defrost") {
      delete $empty_events->{freeze};
    }
    $empty_events;
  };
  $self->save_state(%params);
}

sub create_statefilesdir {
  my ($self) = @_;
  if (! -d $self->statefilesdir()) {
    eval {
      use File::Path;
      mkpath $self->statefilesdir();
    };
    if ($@ || ! -w $self->statefilesdir()) {
      $self->add_message(UNKNOWN,
        sprintf "cannot create status dir %s! check your filesystem (permissions/usage/integrity) and disk devices", $self->statefilesdir());
    }
  } elsif (! -w $self->statefilesdir()) {
    $self->add_message(UNKNOWN,
        sprintf "cannot write status dir %s! check your filesystem (permissions/usage/integrity) and disk devices", $self->statefilesdir());
  }
}

sub create_statefile {
  my ($self, %params) = @_;
  my $extension = "";
  $extension .= $params{name} ? '_'.$params{name} : '';
  $extension =~ s/\//_/g;
  $extension =~ s/\(/_/g;
  $extension =~ s/\)/_/g;
  $extension =~ s/\*/_/g;
  $extension =~ s/\s/_/g;
  return sprintf "%s/%s%s", $self->statefilesdir(),
      $self->clean_path($self->mode), $self->clean_path(lc $extension);
}

sub clean_path {
  my ($self, $path) = @_;
  if ($^O =~ /MSWin/) {
    $path =~ s/:/_/g;
  }
  return $path;
}

sub schimpf {
  my ($self) = @_;
  printf "statefilesdir %s is not writable.\nYou didn't run this plugin as root, didn't you?\n", $self->statefilesdir();
}

# $self->protect_value('1.1-flat_index', 'cpu_busy', 'percent');
sub protect_value {
  my ($self, $ident, $key, $validfunc) = @_;
  if (ref($validfunc) ne "CODE" && $validfunc eq "percent") {
    $validfunc = sub {
      my $value = shift;
      return 0 if $value !~ /^[-+]?([0-9]+(\.[0-9]+)?|\.[0-9]+)$/;
      return ($value < 0 || $value > 100) ? 0 : 1;
    };
  } elsif (ref($validfunc) ne "CODE" && $validfunc eq "positive") {
    $validfunc = sub {
      my $value = shift;
      return 0 if $value !~ /^[-+]?([0-9]+(\.[0-9]+)?|\.[0-9]+)$/;
      return ($value < 0) ? 0 : 1;
    };
  }
  if (&$validfunc($self->{$key})) {
    $self->save_state(name => 'protect_'.$ident.'_'.$key, save => {
        $key => $self->{$key},
        exception => 0,
    });
  } else {
    # if the device gives us an clearly wrong value, simply use the last value.
    my $laststate = $self->load_state(name => 'protect_'.$ident.'_'.$key);
    $self->debug(sprintf "self->{%s} is %s and invalid for the %dth time",
        $key, $self->{$key}, $laststate->{exception} + 1);
    if ($laststate->{exception} <= 5) {
      # but only 5 times.
      # if the error persists, somebody has to check the device.
      $self->{$key} = $laststate->{$key};
    }
    $self->save_state(name => 'protect_'.$ident.'_'.$key, save => {
        $key => $laststate->{$key},
        exception => ++$laststate->{exception},
    });
  }
}

sub save_state {
  my ($self, %params) = @_;
  $self->create_statefilesdir();
  my $statefile = $self->create_statefile(%params);
  my $tmpfile = $self->statefilesdir().'/check__health_tmp_'.$$;
  if ((ref($params{save}) eq "HASH") && exists $params{save}->{timestamp}) {
    $params{save}->{localtime} = scalar localtime $params{save}->{timestamp};
  }
  my $seekfh = IO::File->new();
  if ($seekfh->open($tmpfile, "w")) {
    $seekfh->printf("%s", Data::Dumper::Dumper($params{save}));
    $seekfh->flush();
    $seekfh->close();
    $self->debug(sprintf "saved %s to %s",
        Data::Dumper::Dumper($params{save}), $statefile);
  }
  if (! rename $tmpfile, $statefile) {
    $self->add_message(UNKNOWN,
        sprintf "cannot write status file %s! check your filesystem (permissions/usage/integrity) and disk devices", $statefile);
  }
}

sub load_state {
  my ($self, %params) = @_;
  my $statefile = $self->create_statefile(%params);
  if ( -f $statefile) {
    our $VAR1;
    eval {
      delete $INC{$statefile} if exists $INC{$statefile}; # else unit tests fail
      require $statefile;
    };
    if($@) {
      printf "rumms\n";
    }
    $self->debug(sprintf "load %s from %s", Data::Dumper::Dumper($VAR1), $statefile);
    return $VAR1;
  } else {
    return undef;
  }
}

#########################################################
# daemon mode
#
sub check_pidfile {
  my ($self) = @_;
  my $fh = IO::File->new();
  if ($fh->open($self->{pidfile}, "r")) {
    my $pid = $fh->getline();
    $fh->close();
    if (! $pid) {
      $self->debug("Found pidfile %s with no valid pid. Exiting.",
          $self->{pidfile});
      return 0;
    } else {
      $self->debug("Found pidfile %s with pid %d", $self->{pidfile}, $pid);
      kill 0, $pid;
      if ($! == Errno::ESRCH) {
        $self->debug("This pidfile is stale. Writing a new one");
        $self->write_pidfile();
        return 1;
      } else {
        $self->debug("This pidfile is held by a running process. Exiting");
        return 0;
      }
    }
  } else {
    $self->debug("Found no pidfile. Writing a new one");
    $self->write_pidfile();
    return 1;
  }
}

sub write_pidfile {
  my ($self) = @_;
  if (! -d dirname($self->{pidfile})) {
    eval "require File::Path;";
    if (defined(&File::Path::mkpath)) {
      import File::Path;
      eval { mkpath(dirname($self->{pidfile})); };
    } else {
      my @dirs = ();
      map {
          push @dirs, $_;
          mkdir(join('/', @dirs))
              if join('/', @dirs) && ! -d join('/', @dirs);
      } split(/\//, dirname($self->{pidfile}));
    }
  }
  my $fh = IO::File->new();
  $fh->autoflush(1);
  if ($fh->open($self->{pidfile}, "w")) {
    $fh->printf("%s", $$);
    $fh->close();
  } else {
    $self->debug("Could not write pidfile %s", $self->{pidfile});
    die "pid file could not be written";
  }
}

sub system_vartmpdir {
  my ($self) = @_;
  if ($^O =~ /MSWin/) {
    return $self->system_tmpdir();
  } else {
    return "/var/tmp/".$Monitoring::GLPlugin::pluginname;
  }
}

sub system_tmpdir {
  my ($self) = @_;
  if ($^O =~ /MSWin/) {
    return $ENV{TEMP} if defined $ENV{TEMP};
    return $ENV{TMP} if defined $ENV{TMP};
    return File::Spec->catfile($ENV{windir}, 'Temp')
        if defined $ENV{windir};
    return 'C:\Temp';
  } else {
    return "/tmp";
  }
}

sub convert_scientific_numbers {
  my ($self, $n) = @_;
  # mostly used to convert numbers in scientific notation
  if ($n =~ /^\s*\d+\s*$/) {
    return $n;
  } elsif ($n =~ /^\s*([-+]?)(\d*[\.,]*\d*)[eE]{1}([-+]?)(\d+)\s*$/) {
    my ($vor, $num, $sign, $exp) = ($1, $2, $3, $4);
    $n =~ s/E/e/g;
    $n =~ s/,/\./g;
    $num =~ s/,/\./g;
    my $sig = $sign eq '-' ? "." . ($exp - 1 + length $num) : '';
    my $dec = sprintf "%${sig}f", $n;
    $dec =~ s/\.[0]+$//g;
    return $dec;
  } elsif ($n =~ /^\s*([-+]?)(\d+)[\.,]*(\d*)\s*$/) {
    return $1.$2.".".$3;
  } elsif ($n =~ /^\s*(.*?)\s*$/) {
    return $1;
  } else {
    return $n;
  }
}

sub compatibility_methods {
  my ($self) = @_;
  # add_perfdata
  # add_message
  # nagios_exit
  # ->{warningrange}
  # ->{criticalrange}
  # ...
  $self->{warningrange} = ($self->get_thresholds())[0];
  $self->{criticalrange} = ($self->get_thresholds())[1];
  my $old_init = $self->can('init');
  my %params = (
    'mode' => join('::', split(/-/, $self->opts->mode)),
    'name' => $self->opts->name,
    'name2' => $self->opts->name2,
  );
  {
    no strict 'refs';
    no warnings 'redefine';
    *{ref($self).'::init'} = sub {
      $self->$old_init(%params);
      $self->nagios(%params);
    };
    *{ref($self).'::add_nagios'} = \&{"Monitoring::GLPlugin::add_message"};
    *{ref($self).'::add_nagios_ok'} = \&{"Monitoring::GLPlugin::add_ok"};
    *{ref($self).'::add_nagios_warning'} = \&{"Monitoring::GLPlugin::add_warning"};
    *{ref($self).'::add_nagios_critical'} = \&{"Monitoring::GLPlugin::add_critical"};
    *{ref($self).'::add_nagios_unknown'} = \&{"Monitoring::GLPlugin::add_unknown"};
    *{ref($self).'::add_perfdata'} = sub {
      my $self = shift;
      my $message = shift;
      foreach my $perfdata (split(/\s+/, $message)) {
      my ($label, $perfstr) = split(/=/, $perfdata);
      my ($value, $warn, $crit, $min, $max) = split(/;/, $perfstr);
      $value =~ /^([\d\.\-\+]+)(.*)$/;
      $value = $1;
      my $uom = $2;
      $Monitoring::GLPlugin::plugin->add_perfdata(
        label => $label,
        value => $value,
        uom => $uom,
        warn => $warn,
        crit => $crit,
        min => $min,
        max => $max,
      );
      }
    };
    *{ref($self).'::check_thresholds'} = sub {
      my $self = shift;
      my $value = shift;
      my $defaultwarningrange = shift;
      my $defaultcriticalrange = shift;
      $Monitoring::GLPlugin::plugin->set_thresholds(
          metric => 'default',
          warning => $defaultwarningrange,
          critical => $defaultcriticalrange,
      );
      $self->{warningrange} = ($self->get_thresholds())[0];
      $self->{criticalrange} = ($self->get_thresholds())[1];
      return $Monitoring::GLPlugin::plugin->check_thresholds(
          metric => 'default',
          value => $value,
          warning => $defaultwarningrange,
          critical => $defaultcriticalrange,
      );
    };
  }
}


sub AUTOLOAD {
  my ($self, @params) = @_;
  return if ($AUTOLOAD =~ /DESTROY/);
  $self->debug("AUTOLOAD %s\n", $AUTOLOAD)
        if $self->opts->verbose >= 2;
  if ($AUTOLOAD =~ /^(.*)::analyze_and_check_(.*)_subsystem$/) {
    my $class = $1;
    my $subsystem = $2;
    my $analyze = sprintf "analyze_%s_subsystem", $subsystem;
    my $check = sprintf "check_%s_subsystem", $subsystem;
    if (@params) {
      # analyzer class
      my $subsystem_class = shift @params;
      $self->{components}->{$subsystem.'_subsystem'} = $subsystem_class->new();
      $self->debug(sprintf "\$self->{components}->{%s_subsystem} = %s->new()",
          $subsystem, $subsystem_class);
    } else {
      $self->$analyze();
      $self->debug("call %s()", $analyze);
    }
    $self->$check();
  } elsif ($AUTOLOAD =~ /^(.*)::check_(.*)_subsystem$/) {
    my $class = $1;
    my $subsystem = sprintf "%s_subsystem", $2;
    $self->{components}->{$subsystem}->check();
    $self->{components}->{$subsystem}->dump()
        if $self->opts->verbose >= 2;
  } elsif ($AUTOLOAD =~ /^.*::(status_code|check_messages|nagios_exit|html_string|perfdata_string|selected_perfdata|check_thresholds|get_thresholds|opts)$/) {
    return $Monitoring::GLPlugin::plugin->$1(@params);
  } elsif ($AUTOLOAD =~ /^.*::(reduce_messages|reduce_messages_short|clear_messages|suppress_messages|add_html|add_perfdata|override_opt|create_opt|set_thresholds|force_thresholds)$/) {
    $Monitoring::GLPlugin::plugin->$1(@params);
  } elsif ($AUTOLOAD =~ /^.*::mod_arg_(.*)$/) {
    return $Monitoring::GLPlugin::plugin->mod_arg($1, @params);
  } else {
    $self->debug("AUTOLOAD: class %s has no method %s\n",
        ref($self), $AUTOLOAD);
  }
}



package Monitoring::GLPlugin::Item;
our @ISA = qw(Monitoring::GLPlugin);

use strict;

sub new {
  my ($class, %params) = @_;
  my $self = {
    blacklisted => 0,
    info => undef,
    extendedinfo => undef,
  };
  bless $self, $class;
  $self->init(%params);
  return $self;
}

sub check {
  my ($self, $lists) = @_;
  my @lists = $lists ? @{$lists} : grep { ref($self->{$_}) eq "ARRAY" } keys %{$self};
  foreach my $list (@lists) {
    $self->add_info('checking '.$list);
    foreach my $element (@{$self->{$list}}) {
      $element->blacklist() if $self->is_blacklisted();
      $element->check();
    }
  }
}



package Monitoring::GLPlugin::TableItem;
our @ISA = qw(Monitoring::GLPlugin::Item);

use strict;

sub new {
  my ($class, %params) = @_;
  my $self = {};
  bless $self, $class;
  foreach (keys %params) {
    $self->{$_} = $params{$_};
  }
  if ($self->can("finish")) {
    $self->finish(%params);
  }
  return $self;
}

sub check {
  my ($self) = @_;
  # some tableitems are not checkable, they are only used to enhance other
  # items (e.g. sensorthresholds enhance sensors)
  # normal tableitems should have their own check-method
}



package Monitoring::GLPlugin::SNMP;
our @ISA = qw(Monitoring::GLPlugin);
# ABSTRACT: helper functions to build a snmp-based monitoring plugin

use strict;
use File::Basename;
use Digest::MD5 qw(md5_hex);
use Module::Load;
use AutoLoader;
our $AUTOLOAD;

use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };

{
  our $mode = undef;
  our $plugin = undef;
  our $blacklist = undef;
  our $session = undef;
  our $rawdata = {};
  our $tablecache = {};
  our $info = [];
  our $extendedinfo = [];
  our $summary = [];
  our $oidtrace = [];
  our $uptime = 0;
}

sub new {
  my ($class, %params) = @_;
  require Monitoring::GLPlugin
      if ! grep /BEGIN/, keys %Monitoring::GLPlugin::;
  require Monitoring::GLPlugin::SNMP::MibsAndOids
      if ! grep /BEGIN/, keys %Monitoring::GLPlugin::SNMP::MibsAndOids::;
  require Monitoring::GLPlugin::SNMP::CSF
      if ! grep /BEGIN/, keys %Monitoring::GLPlugin::SNMP::CSF::;
  require Monitoring::GLPlugin::SNMP::Item
      if ! grep /BEGIN/, keys %Monitoring::GLPlugin::SNMP::Item::;
  require Monitoring::GLPlugin::SNMP::TableItem
      if ! grep /BEGIN/, keys %Monitoring::GLPlugin::SNMP::TableItem::;
  my $self = Monitoring::GLPlugin->new(%params);
  bless $self, $class;
  return $self;
}

sub v2tov3 {
  my ($self) = @_;
  if ($self->opts->community && $self->opts->community =~ /^snmpv3(.)(.+)/) {
    my $separator = $1;
    my ($authprotocol, $authpassword, $privprotocol, $privpassword,
        $username, $contextengineid, $contextname) = split(/$separator/, $2);
    $self->override_opt('authprotocol', $authprotocol) 
        if defined($authprotocol) && $authprotocol;
    $self->override_opt('authpassword', $authpassword) 
        if defined($authpassword) && $authpassword;
    $self->override_opt('privprotocol', $privprotocol) 
        if defined($privprotocol) && $privprotocol;
    $self->override_opt('privpassword', $privpassword) 
        if defined($privpassword) && $privpassword;
    $self->override_opt('username', $username) 
        if defined($username) && $username;
    $self->override_opt('contextengineid', $contextengineid) 
        if defined($contextengineid) && $contextengineid;
    $self->override_opt('contextname', $contextname) 
        if defined($contextname) && $contextname;
    $self->override_opt('protocol', '3') ;
  }
  if (($self->opts->authpassword || $self->opts->authprotocol ||
      $self->opts->privpassword || $self->opts->privprotocol) && 
      ! $self->opts->protocol eq '3') {
    $self->override_opt('protocol', '3') ;
  }
}

sub add_snmp_modes {
  my ($self) = @_;
  $self->add_mode(
      internal => 'device::uptime',
      spec => 'uptime',
      alias => undef,
      help => 'Check the uptime of the device',
  );
  $self->add_mode(
      internal => 'device::walk',
      spec => 'walk',
      alias => undef,
      help => 'Show snmpwalk command with the oids necessary for a simulation',
  );
  $self->add_mode(
      internal => 'device::supportedmibs',
      spec => 'supportedmibs',
      alias => undef,
      help => 'Shows the names of the mibs which this devices has implemented (only lausser may run this command)',
  );
}

sub add_snmp_args {
  my ($self) = @_;
  $self->add_arg(
      spec => 'hostname|H=s',
      help => '--hostname
   Hostname or IP-address of the switch or router',
      required => 0,
      env => 'HOSTNAME',
  );
  $self->add_arg(
      spec => 'port=i',
      help => '--port
   The SNMP port to use (default: 161)',
      required => 0,
      default => 161,
  );
  $self->add_arg(
      spec => 'domain=s',
      help => '--domain
   The transport domain to use (default: udp/ipv4, other possible values: udp6, udp/ipv6, tcp, tcp4, tcp/ipv4, tcp6, tcp/ipv6)',
      required => 0,
      default => 'udp',
  );
  $self->add_arg(
      spec => 'protocol|P=s',
      help => '--protocol
   The SNMP protocol to use (default: 2c, other possibilities: 1,3)',
      required => 0,
      default => '2c',
  );
  $self->add_arg(
      spec => 'community|C=s',
      help => '--community
   SNMP community of the server (SNMP v1/2 only)',
      required => 0,
      default => 'public',
  );
  $self->add_arg(
      spec => 'username:s',
      help => '--username
   The securityName for the USM security model (SNMPv3 only)',
      required => 0,
  );
  $self->add_arg(
      spec => 'authpassword:s',
      help => '--authpassword
   The authentication password for SNMPv3',
      required => 0,
  );
  $self->add_arg(
      spec => 'authprotocol:s',
      help => '--authprotocol
   The authentication protocol for SNMPv3 (md5|sha)',
      required => 0,
  );
  $self->add_arg(
      spec => 'privpassword:s',
      help => '--privpassword
   The password for authPriv security level',
      required => 0,
  );
  $self->add_arg(
      spec => 'privprotocol=s',
      help => '--privprotocol
   The private protocol for SNMPv3 (des|aes|aes128|3des|3desde)',
      required => 0,
  );
  $self->add_arg(
      spec => 'contextengineid=s',
      help => '--contextengineid
   The context engine id for SNMPv3 (10 to 64 hex characters)',
      required => 0,
  );
  $self->add_arg(
      spec => 'contextname=s',
      help => '--contextname
   The context name for SNMPv3 (empty represents the "default" context)',
      required => 0,
  );
  $self->add_arg(
      spec => 'community2=s',
      help => '--community2
   SNMP community which can be used to switch the context during runtime',
      required => 0,
  );
  $self->add_arg(
      spec => 'snmpwalk=s',
      help => '--snmpwalk
   A file with the output of a snmpwalk (used for simulation)
   Use it instead of --hostname',
      required => 0,
      env => 'SNMPWALK',
  );
  $self->add_arg(
      spec => 'servertype=s',
      help => '--servertype
     The type of the network device: cisco (default). Use it if auto-detection
     is not possible',
      required => 0,
  );
  $self->add_arg(
      spec => 'oids=s',
      help => '--oids
   A list of oids which are downloaded and written to a cache file.
   Use it together with --mode oidcache',
      required => 0,
  );
  $self->add_arg(
      spec => 'offline:i',
      help => '--offline
   The maximum number of seconds since the last update of cache file before
   it is considered too old',
      required => 0,
      env => 'OFFLINE',
  );
}

sub validate_args {
  my ($self) = @_;
  $self->SUPER::validate_args();
  if ($self->opts->mode eq 'walk') {
    if ($self->opts->snmpwalk && $self->opts->hostname) {
      if ($self->check_messages == CRITICAL) {
        # gemecker vom super-validierer, der sicherstellt, dass die datei
        # snmpwalk existiert. in diesem fall wird sie aber erst neu angelegt,
        # also schnauze.
        my ($code, $message) = $self->check_messages;
        if ($message eq sprintf("file %s not found", $self->opts->snmpwalk)) {
          $self->clear_critical;
        }
      }
      # snmp agent wird abgefragt, die ergebnisse landen in einem file
      # opts->snmpwalk ist der filename. da sich die ganzen get_snmp_table/object-aufrufe
      # an das walkfile statt an den agenten halten wuerden, muss opts->snmpwalk geloescht
      # werden. stattdessen wird opts->snmpdump als traeger des dateinamens mitgegeben.
      # nur sinnvoll mit mode=walk
      $self->create_opt('snmpdump');
      $self->override_opt('snmpdump', $self->opts->snmpwalk);
      $self->override_opt('snmpwalk', undef);
    } elsif (! $self->opts->snmpwalk && $self->opts->hostname && $self->opts->mode eq 'walk') {   
      # snmp agent wird abgefragt, die ergebnisse landen in einem file, dessen name
      # nicht vorgegeben ist
      $self->create_opt('snmpdump');
    }
  } else {    
    if ($self->opts->snmpwalk && ! $self->opts->hostname) {
      # normaler aufruf, mode != walk, oid-quelle ist eine datei
      $self->override_opt('hostname', 'snmpwalk.file'.md5_hex($self->opts->snmpwalk))
    } elsif ($self->opts->snmpwalk && $self->opts->hostname) {
      # snmpwalk hat vorrang
      $self->override_opt('hostname', undef);
    }
  }
}

sub init {
  my ($self) = @_;
  if ($self->mode =~ /device::walk/) {
    my @trees = ();
    my $name = $Monitoring::GLPlugin::pluginname;
    $name =~ s/.*\///g;
    $name = sprintf "/tmp/snmpwalk_%s_%s", $name, $self->opts->hostname;
    if ($self->opts->oids) {
      # create pid filename
      # already running?;x
      @trees = split(",", $self->opts->oids);

    } elsif ($self->can("trees")) {
      @trees = $self->trees;
      push(@trees, "1.3.6.1.2.1.1");
    } else {
      @trees = ("1.3.6.1.2.1", "1.3.6.1.4.1");
    }
    if ($self->opts->snmpdump) {
      $name = $self->opts->snmpdump;
    }
    $self->opts->override_opt("protocol", $1) if $self->opts->protocol =~ /^v(.*)/;
    if (defined $self->opts->offline) {
      $self->{pidfile} = $name.".pid";
      if (! $self->check_pidfile()) {
        $self->debug("Exiting because another walk is already running");
        printf STDERR "Exiting because another walk is already running\n";
        exit 3;
      }
      $self->write_pidfile();
      my $timedout = 0;
      my $snmpwalkpid = 0;
      $SIG{'ALRM'} = sub {
        $timedout = 1;
        printf "UNKNOWN - %s timed out after %d seconds\n",
            $Monitoring::GLPlugin::plugin->{name}, $self->opts->timeout;
        kill 9, $snmpwalkpid;
      };
      alarm($self->opts->timeout);
      unlink $name.".partial";
      while (! $timedout && @trees) {
        my $tree = shift @trees;
        $SIG{CHLD} = 'IGNORE';
        my $cmd = sprintf "snmpwalk -ObentU -v%s -c %s %s %s >> %s", 
            $self->opts->protocol,
            $self->opts->community,
            $self->opts->hostname,
            $tree, $name.".partial";
        $self->debug($cmd);
        $snmpwalkpid = fork;
        if (not $snmpwalkpid) {
          exec($cmd);
        } else {
          wait();
        }
      }
      rename $name.".partial", $name if ! $timedout;
      -f $self->{pidfile} && unlink $self->{pidfile};
      if ($timedout) {
        printf "CRITICAL - timeout. There are still %d snmpwalks left\n", scalar(@trees);
        exit 3;
      } else {
        printf "OK - all requested oids are in %s\n", $name;
      }
    } else {
      printf "rm -f %s\n", $name;
      foreach (@trees) {
        printf "snmpwalk -ObentU -v%s -c %s %s %s >> %s\n", 
            $self->opts->protocol,
            $self->opts->community,
            $self->opts->hostname,
            $_, $name;
      }
    }
    exit 0;
  } elsif ($self->mode =~ /device::uptime/) {
    $self->add_info(sprintf 'device is up since %s',
        $self->human_timeticks($self->{uptime}));
    $self->set_thresholds(warning => '15:', critical => '5:');
    $self->add_message($self->check_thresholds($self->{uptime} / 60));
    $self->add_perfdata(
        label => 'uptime',
        value => $self->{uptime} / 60,
        places => 0,
    );
    my ($code, $message) = $self->check_messages(join => ', ', join_all => ', ');
    $Monitoring::GLPlugin::plugin->nagios_exit($code, $message);
  } elsif ($self->mode =~ /device::supportedmibs/) {
    our $mibdepot = [];
    my $unknowns = {};
    my @outputlist = ();
    %{$unknowns} = %{$self->rawdata};
    if ($self->opts->name && -f $self->opts->name) {
      eval { require $self->opts->name };
      $self->add_critical($@) if $@;
    } elsif ($self->opts->name && ! -f $self->opts->name) {
      $self->add_unknown("where is --name mibdepotfile?");
    }
    push(@{$mibdepot}, ['1.3.6.1.2.1.60', 'ietf', 'v2', 'ACCOUNTING-CONTROL-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.238', 'ietf', 'v2', 'ADSL2-LINE-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.238.2', 'ietf', 'v2', 'ADSL2-LINE-TC-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.94.3', 'ietf', 'v2', 'ADSL-LINE-EXT-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.94', 'ietf', 'v2', 'ADSL-LINE-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.94.2', 'ietf', 'v2', 'ADSL-TC-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.74', 'ietf', 'v2', 'AGENTX-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.3.123', 'ietf', 'v2', 'AGGREGATE-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.118', 'ietf', 'v2', 'ALARM-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.16.23', 'ietf', 'v2', 'APM-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.34.3', 'ietf', 'v2', 'APPC-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.13.1', 'ietf', 'v1', 'APPLETALK-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.27', 'ietf', 'v2', 'APPLICATION-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.62', 'ietf', 'v2', 'APPLICATION-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.34.5', 'ietf', 'v2', 'APPN-DLUR-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.34.4', 'ietf', 'v2', 'APPN-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.34.4', 'ietf', 'v2', 'APPN-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.34.4.0', 'ietf', 'v2', 'APPN-TRAP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.49', 'ietf', 'v2', 'APS-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.117', 'ietf', 'v2', 'ARC-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.37.1.14', 'ietf', 'v2', 'ATM2-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.59', 'ietf', 'v2', 'ATM-ACCOUNTING-INFORMATION-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.37', 'ietf', 'v2', 'ATM-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.37', 'ietf', 'v2', 'ATM-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.37.3', 'ietf', 'v2', 'ATM-TC-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.15', 'ietf', 'v2', 'BGP4-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.15', 'ietf', 'v2', 'BGP4-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.3.122', 'ietf', 'v2', 'BLDG-HVAC-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.17.1', 'ietf', 'v1', 'BRIDGE-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.17', 'ietf', 'v2', 'BRIDGE-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.19', 'ietf', 'v2', 'CHARACTER-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.94', 'ietf', 'v2', 'CIRCUIT-IF-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.3.1.1', 'ietf', 'v1', 'CLNS-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.3.1.1', 'ietf', 'v1', 'CLNS-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.132', 'ietf', 'v2', 'COFFEE-POT-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.89', 'ietf', 'v2', 'COPS-CLIENT-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.18.1', 'ietf', 'v1', 'DECNET-PHIV-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.21', 'ietf', 'v2', 'DIAL-CONTROL-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.108', 'ietf', 'v2', 'DIFFSERV-CONFIG-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.97', 'ietf', 'v2', 'DIFFSERV-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.66', 'ietf', 'v2', 'DIRECTORY-SERVER-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.88', 'ietf', 'v2', 'DISMAN-EVENT-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.90', 'ietf', 'v2', 'DISMAN-EXPRESSION-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.82', 'ietf', 'v2', 'DISMAN-NSLOOKUP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.82', 'ietf', 'v2', 'DISMAN-NSLOOKUP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.80', 'ietf', 'v2', 'DISMAN-PING-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.80', 'ietf', 'v2', 'DISMAN-PING-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.63', 'ietf', 'v2', 'DISMAN-SCHEDULE-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.63', 'ietf', 'v2', 'DISMAN-SCHEDULE-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.64', 'ietf', 'v2', 'DISMAN-SCRIPT-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.64', 'ietf', 'v2', 'DISMAN-SCRIPT-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.81', 'ietf', 'v2', 'DISMAN-TRACEROUTE-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.81', 'ietf', 'v2', 'DISMAN-TRACEROUTE-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.46', 'ietf', 'v2', 'DLSW-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.32.2', 'ietf', 'v2', 'DNS-RESOLVER-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.32.1', 'ietf', 'v2', 'DNS-SERVER-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.127.5', 'ietf', 'v2', 'DOCS-BPI-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.69', 'ietf', 'v2', 'DOCS-CABLE-DEVICE-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.69', 'ietf', 'v2', 'DOCS-CABLE-DEVICE-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.126', 'ietf', 'v2', 'DOCS-IETF-BPI2-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.132', 'ietf', 'v2', 'DOCS-IETF-CABLE-DEVICE-NOTIFICATION-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.127', 'ietf', 'v2', 'DOCS-IETF-QOS-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.125', 'ietf', 'v2', 'DOCS-IETF-SUBMGT-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.127', 'ietf', 'v2', 'DOCS-IF-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.127', 'ietf', 'v2', 'DOCS-IF-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.45', 'ietf', 'v2', 'DOT12-IF-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.53', 'ietf', 'v2', 'DOT12-RPTR-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.155', 'ietf', 'v2', 'DOT3-EPON-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.158', 'ietf', 'v2', 'DOT3-OAM-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.4.1.2.2.1.1', 'ietf', 'v1', 'DPI20-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.82', 'ietf', 'v2', 'DS0BUNDLE-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.81', 'ietf', 'v2', 'DS0-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.18', 'ietf', 'v2', 'DS1-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.18', 'ietf', 'v2', 'DS1-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.18', 'ietf', 'v2', 'DS1-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.30', 'ietf', 'v2', 'DS3-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.30', 'ietf', 'v2', 'DS3-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.29', 'ietf', 'v2', 'DSA-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.16.26', 'ietf', 'v2', 'DSMON-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.34.7', 'ietf', 'v2', 'EBN-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.167', 'ietf', 'v2', 'EFM-CU-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.47', 'ietf', 'v2', 'ENTITY-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.47', 'ietf', 'v2', 'ENTITY-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.47', 'ietf', 'v2', 'ENTITY-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.99', 'ietf', 'v2', 'ENTITY-SENSOR-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.131', 'ietf', 'v2', 'ENTITY-STATE-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.130', 'ietf', 'v2', 'ENTITY-STATE-TC-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.70', 'ietf', 'v2', 'ETHER-CHIPSET-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.7', 'ietf', 'v1', 'EtherLike-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.7', 'ietf', 'v1', 'EtherLike-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.35', 'ietf', 'v2', 'EtherLike-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.35', 'ietf', 'v2', 'EtherLike-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.35', 'ietf', 'v2', 'EtherLike-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.35', 'ietf', 'v2', 'EtherLike-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.224', 'ietf', 'v2', 'FCIP-MGMT-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.56', 'ietf', 'v2', 'FC-MGMT-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.15.73.1', 'ietf', 'v1', 'FDDI-SMT73-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.75', 'ietf', 'v2', 'FIBRE-CHANNEL-FE-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.111', 'ietf', 'v2', 'Finisher-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.40', 'ietf', 'v2', 'FLOW-METER-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.40', 'ietf', 'v2', 'FLOW-METER-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.32', 'ietf', 'v2', 'FRAME-RELAY-DTE-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.86', 'ietf', 'v2', 'FR-ATM-PVC-SERVICE-IWF-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.47', 'ietf', 'v2', 'FR-MFR-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.44', 'ietf', 'v2', 'FRNETSERV-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.44', 'ietf', 'v2', 'FRNETSERV-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.44', 'ietf', 'v2', 'FRNETSERV-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.95', 'ietf', 'v2', 'FRSLD-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.166.16', 'ietf', 'v2', 'GMPLS-LABEL-STD-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.166.15', 'ietf', 'v2', 'GMPLS-LSR-STD-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.166.12', 'ietf', 'v2', 'GMPLS-TC-STD-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.166.13', 'ietf', 'v2', 'GMPLS-TE-STD-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.98', 'ietf', 'v2', 'GSMP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.16.29', 'ietf', 'v2', 'HC-ALARM-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.107', 'ietf', 'v2', 'HC-PerfHist-TC-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.16.20.5', 'ietf', 'v2', 'HC-RMON-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.25.1', 'ietf', 'v1', 'HOST-RESOURCES-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.25.7.1', 'ietf', 'v2', 'HOST-RESOURCES-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.34.6.1.5', 'ietf', 'v2', 'HPR-IP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.34.6', 'ietf', 'v2', 'HPR-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.106', 'ietf', 'v2', 'IANA-CHARSET-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.110', 'ietf', 'v2', 'IANA-FINISHER-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.152', 'ietf', 'v2', 'IANA-GMPLS-TC-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.30', 'ietf', 'v2', 'IANAifType-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.128', 'ietf', 'v2', 'IANA-IPPM-METRICS-REGISTRY-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.119', 'ietf', 'v2', 'IANA-ITU-ALARM-TC-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.154', 'ietf', 'v2', 'IANA-MAU-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.109', 'ietf', 'v2', 'IANA-PRINTER-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.4.1.2.6.2.13.1.1', 'ietf', 'v1', 'IBM-6611-APPN-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.166', 'ietf', 'v2', 'IF-CAP-STACK-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.230', 'ietf', 'v2', 'IFCP-MGMT-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.77', 'ietf', 'v2', 'IF-INVERTED-STACK-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.31', 'ietf', 'v2', 'IF-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.31', 'ietf', 'v2', 'IF-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.31', 'ietf', 'v2', 'IF-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.85', 'ietf', 'v2', 'IGMP-STD-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.76', 'ietf', 'v2', 'INET-ADDRESS-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.76', 'ietf', 'v2', 'INET-ADDRESS-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.76', 'ietf', 'v2', 'INET-ADDRESS-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.52.5', 'ietf', 'v2', 'INTEGRATED-SERVICES-GUARANTEED-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.52', 'ietf', 'v2', 'INTEGRATED-SERVICES-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.16.27', 'ietf', 'v2', 'INTERFACETOPN-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.17', 'ietf', 'v2', 'IPATM-IPMC-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.57', 'ietf', 'v2', 'IPATM-IPMC-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.4.24', 'ietf', 'v2', 'IP-FORWARD-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.4.24', 'ietf', 'v2', 'IP-FORWARD-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.168', 'ietf', 'v2', 'IPMCAST-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.48', 'ietf', 'v2', 'IP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.48', 'ietf', 'v2', 'IP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.83', 'ietf', 'v2', 'IPMROUTE-STD-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.46', 'ietf', 'v2', 'IPOA-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.141', 'ietf', 'v2', 'IPS-AUTH-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.153', 'ietf', 'v2', 'IPSEC-SPD-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.103', 'ietf', 'v2', 'IPV6-FLOW-LABEL-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.56', 'ietf', 'v2', 'IPV6-ICMP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.55', 'ietf', 'v2', 'IPV6-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.91', 'ietf', 'v2', 'IPV6-MLD-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.3.86', 'ietf', 'v2', 'IPV6-TCP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.3.87', 'ietf', 'v2', 'IPV6-UDP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.142', 'ietf', 'v2', 'ISCSI-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.20', 'ietf', 'v2', 'ISDN-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.138', 'ietf', 'v2', 'ISIS-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.163', 'ietf', 'v2', 'ISNS-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.121', 'ietf', 'v2', 'ITU-ALARM-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.120', 'ietf', 'v2', 'ITU-ALARM-TC-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.4.1.2699.1.1', 'ietf', 'v2', 'Job-Monitoring-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.95', 'ietf', 'v2', 'L2TP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.165', 'ietf', 'v2', 'LANGTAG-TC-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.227', 'ietf', 'v2', 'LMP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.227', 'ietf', 'v2', 'LMP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.101', 'ietf', 'v2', 'MALLOC-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.26.1', 'ietf', 'v1', 'MAU-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.26.6', 'ietf', 'v2', 'MAU-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.26.6', 'ietf', 'v2', 'MAU-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.26.6', 'ietf', 'v2', 'MAU-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.26.6', 'ietf', 'v2', 'MAU-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.171', 'ietf', 'v2', 'MIDCOM-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.38.1', 'ietf', 'v1', 'MIOX25-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.44', 'ietf', 'v2', 'MIP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.133', 'ietf', 'v2', 'MOBILEIPV6-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.38', 'ietf', 'v2', 'Modem-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.166.8', 'ietf', 'v2', 'MPLS-FTN-STD-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.166.11', 'ietf', 'v2', 'MPLS-L3VPN-STD-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.166.9', 'ietf', 'v2', 'MPLS-LC-ATM-STD-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.166.10', 'ietf', 'v2', 'MPLS-LC-FR-STD-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.166.5', 'ietf', 'v2', 'MPLS-LDP-ATM-STD-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.166.6', 'ietf', 'v2', 'MPLS-LDP-FRAME-RELAY-STD-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.166.7', 'ietf', 'v2', 'MPLS-LDP-GENERIC-STD-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.4.1.9.10.65', 'ietf', 'v2', 'MPLS-LDP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.166.4', 'ietf', 'v2', 'MPLS-LDP-STD-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.166.2', 'ietf', 'v2', 'MPLS-LSR-STD-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.166.1', 'ietf', 'v2', 'MPLS-TC-STD-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.166.3', 'ietf', 'v2', 'MPLS-TE-STD-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.3.92', 'ietf', 'v2', 'MSDP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.28', 'ietf', 'v2', 'MTA-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.28', 'ietf', 'v2', 'MTA-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.28', 'ietf', 'v2', 'MTA-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.123', 'ietf', 'v2', 'NAT-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.27', 'ietf', 'v2', 'NETWORK-SERVICES-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.27', 'ietf', 'v2', 'NETWORK-SERVICES-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.71', 'ietf', 'v2', 'NHRP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.92', 'ietf', 'v2', 'NOTIFICATION-LOG-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.133', 'ietf', 'v2', 'OPT-IF-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.14', 'ietf', 'v2', 'OSPF-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.14', 'ietf', 'v2', 'OSPF-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.14.16', 'ietf', 'v2', 'OSPF-TRAP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.14.16', 'ietf', 'v2', 'OSPF-TRAP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.34', 'ietf', 'v2', 'PARALLEL-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.17.6', 'ietf', 'v2', 'P-BRIDGE-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.58', 'ietf', 'v2', 'PerfHist-TC-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.58', 'ietf', 'v2', 'PerfHist-TC-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.172', 'ietf', 'v2', 'PIM-BSR-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.3.61', 'ietf', 'v2', 'PIM-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.157', 'ietf', 'v2', 'PIM-STD-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.93', 'ietf', 'v2', 'PINT-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.140', 'ietf', 'v2', 'PKTC-IETF-MTA-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.169', 'ietf', 'v2', 'PKTC-IETF-SIG-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.124', 'ietf', 'v2', 'POLICY-BASED-MANAGEMENT-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.105', 'ietf', 'v2', 'POWER-ETHERNET-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.23.4', 'ietf', 'v1', 'PPP-BRIDGE-NCP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.23.3', 'ietf', 'v1', 'PPP-IP-NCP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.23.1.1', 'ietf', 'v1', 'PPP-LCP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.23.2', 'ietf', 'v1', 'PPP-SEC-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.43', 'ietf', 'v2', 'Printer-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.43', 'ietf', 'v2', 'Printer-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.79', 'ietf', 'v2', 'PTOPO-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.17.7', 'ietf', 'v2', 'Q-BRIDGE-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.67.2.2', 'ietf', 'v2', 'RADIUS-ACC-CLIENT-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.67.2.2', 'ietf', 'v2', 'RADIUS-ACC-CLIENT-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.67.2.1', 'ietf', 'v2', 'RADIUS-ACC-SERVER-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.67.2.1', 'ietf', 'v2', 'RADIUS-ACC-SERVER-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.67.1.2', 'ietf', 'v2', 'RADIUS-AUTH-CLIENT-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.67.1.2', 'ietf', 'v2', 'RADIUS-AUTH-CLIENT-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.67.1.1', 'ietf', 'v2', 'RADIUS-AUTH-SERVER-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.67.1.1', 'ietf', 'v2', 'RADIUS-AUTH-SERVER-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.145', 'ietf', 'v2', 'RADIUS-DYNAUTH-CLIENT-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.146', 'ietf', 'v2', 'RADIUS-DYNAUTH-SERVER-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.16.31', 'ietf', 'v2', 'RAQMON-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.16.32', 'ietf', 'v2', 'RAQMON-RDS-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.39', 'ietf', 'v2', 'RDBMS-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.1', 'ietf', 'v1', 'RFC1066-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.1', 'ietf', 'v1', 'RFC1156-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.1', 'ietf', 'v1', 'RFC1158-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.1', 'ietf', 'v1', 'RFC1213-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.12', 'ietf', 'v1', 'RFC1229-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.3.7', 'ietf', 'v1', 'RFC1230-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.9', 'ietf', 'v1', 'RFC1231-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.3.2', 'ietf', 'v1', 'RFC1232-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.3.15', 'ietf', 'v1', 'RFC1233-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.13.1', 'ietf', 'v1', 'RFC1243-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.13.1', 'ietf', 'v1', 'RFC1248-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.13.1', 'ietf', 'v1', 'RFC1252-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.14.1', 'ietf', 'v1', 'RFC1253-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.15', 'ietf', 'v1', 'RFC1269-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.16.1', 'ietf', 'v1', 'RFC1271-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.7', 'ietf', 'v1', 'RFC1284-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.15.1', 'ietf', 'v1', 'RFC1285-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.17.1', 'ietf', 'v1', 'RFC1286-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.18.1', 'ietf', 'v1', 'RFC1289-phivMIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.31', 'ietf', 'v1', 'RFC1304-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.32', 'ietf', 'v1', 'RFC1315-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.19', 'ietf', 'v1', 'RFC1316-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.33', 'ietf', 'v1', 'RFC1317-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.34', 'ietf', 'v1', 'RFC1318-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.20.2', 'ietf', 'v1', 'RFC1353-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.4.24', 'ietf', 'v1', 'RFC1354-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.16', 'ietf', 'v1', 'RFC1381-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.5', 'ietf', 'v1', 'RFC1382-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.23.1', 'ietf', 'v1', 'RFC1389-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.7', 'ietf', 'v1', 'RFC1398-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.18', 'ietf', 'v1', 'RFC1406-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.30', 'ietf', 'v1', 'RFC1407-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.24.1', 'ietf', 'v1', 'RFC1414-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.23', 'ietf', 'v2', 'RIPv2-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.16', 'ietf', 'v2', 'RMON2-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.16', 'ietf', 'v2', 'RMON2-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.16.1', 'ietf', 'v1', 'RMON-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.16.20.8', 'ietf', 'v2', 'RMON-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.112', 'ietf', 'v2', 'ROHC-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.114', 'ietf', 'v2', 'ROHC-RTP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.113', 'ietf', 'v2', 'ROHC-UNCOMPRESSED-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.33', 'ietf', 'v2', 'RS-232-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.134', 'ietf', 'v2', 'RSTP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.51', 'ietf', 'v2', 'RSVP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.87', 'ietf', 'v2', 'RTP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.139', 'ietf', 'v2', 'SCSI-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.104', 'ietf', 'v2', 'SCTP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.4.1.4300.1', 'ietf', 'v2', 'SFLOW-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.149', 'ietf', 'v2', 'SIP-COMMON-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.36', 'ietf', 'v2', 'SIP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.151', 'ietf', 'v2', 'SIP-SERVER-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.148', 'ietf', 'v2', 'SIP-TC-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.150', 'ietf', 'v2', 'SIP-UA-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.3.88', 'ietf', 'v2', 'SLAPM-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.16.22', 'ietf', 'v2', 'SMON-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.4.1.4.4', 'ietf', 'v1', 'SMUX-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.34', 'ietf', 'v2', 'SNA-NAU-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.34', 'ietf', 'v2', 'SNA-NAU-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.41', 'ietf', 'v2', 'SNA-SDLC-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.18', 'ietf', 'v2', 'SNMP-COMMUNITY-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.18', 'ietf', 'v2', 'SNMP-COMMUNITY-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.10', 'ietf', 'v2', 'SNMP-FRAMEWORK-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.10', 'ietf', 'v2', 'SNMP-FRAMEWORK-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.10', 'ietf', 'v2', 'SNMP-FRAMEWORK-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.21', 'ietf', 'v2', 'SNMP-IEEE802-TM-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.11', 'ietf', 'v2', 'SNMP-MPD-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.11', 'ietf', 'v2', 'SNMP-MPD-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.11', 'ietf', 'v2', 'SNMP-MPD-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.13', 'ietf', 'v2', 'SNMP-NOTIFICATION-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.13', 'ietf', 'v2', 'SNMP-NOTIFICATION-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.13', 'ietf', 'v2', 'SNMP-NOTIFICATION-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.14', 'ietf', 'v2', 'SNMP-PROXY-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.14', 'ietf', 'v2', 'SNMP-PROXY-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.14', 'ietf', 'v2', 'SNMP-PROXY-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.22.1.1', 'ietf', 'v1', 'SNMP-REPEATER-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.22.1.1', 'ietf', 'v1', 'SNMP-REPEATER-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.22.5', 'ietf', 'v2', 'SNMP-REPEATER-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.12', 'ietf', 'v2', 'SNMP-TARGET-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.12', 'ietf', 'v2', 'SNMP-TARGET-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.12', 'ietf', 'v2', 'SNMP-TARGET-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.15', 'ietf', 'v2', 'SNMP-USER-BASED-SM-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.15', 'ietf', 'v2', 'SNMP-USER-BASED-SM-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.15', 'ietf', 'v2', 'SNMP-USER-BASED-SM-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.20', 'ietf', 'v2', 'SNMP-USM-AES-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.3.101', 'ietf', 'v2', 'SNMP-USM-DH-OBJECTS-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.2', 'ietf', 'v2', 'SNMPv2-M2M-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.1', 'ietf', 'v2', 'SNMPv2-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.1', 'ietf', 'v2', 'SNMPv2-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.1', 'ietf', 'v2', 'SNMPv2-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.3', 'ietf', 'v2', 'SNMPv2-PARTY-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.6', 'ietf', 'v2', 'SNMPv2-USEC-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.16', 'ietf', 'v2', 'SNMP-VIEW-BASED-ACM-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.16', 'ietf', 'v2', 'SNMP-VIEW-BASED-ACM-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.6.3.16', 'ietf', 'v2', 'SNMP-VIEW-BASED-ACM-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.39', 'ietf', 'v2', 'SONET-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.39', 'ietf', 'v2', 'SONET-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.39', 'ietf', 'v2', 'SONET-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.17.3', 'ietf', 'v1', 'SOURCE-ROUTING-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.16.28', 'ietf', 'v2', 'SSPM-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.54', 'ietf', 'v2', 'SYSAPPL-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.137', 'ietf', 'v2', 'T11-FC-FABRIC-ADDR-MGR-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.162', 'ietf', 'v2', 'T11-FC-FABRIC-CONFIG-SERVER-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.159', 'ietf', 'v2', 'T11-FC-FABRIC-LOCK-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.143', 'ietf', 'v2', 'T11-FC-FSPF-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.135', 'ietf', 'v2', 'T11-FC-NAME-SERVER-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.144', 'ietf', 'v2', 'T11-FC-ROUTE-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.161', 'ietf', 'v2', 'T11-FC-RSCN-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.176', 'ietf', 'v2', 'T11-FC-SP-AUTHENTICATION-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.178', 'ietf', 'v2', 'T11-FC-SP-POLICY-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.179', 'ietf', 'v2', 'T11-FC-SP-SA-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.175', 'ietf', 'v2', 'T11-FC-SP-TC-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.177', 'ietf', 'v2', 'T11-FC-SP-ZONING-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.147', 'ietf', 'v2', 'T11-FC-VIRTUAL-FABRIC-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.160', 'ietf', 'v2', 'T11-FC-ZONE-SERVER-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.136', 'ietf', 'v2', 'T11-TC-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.156', 'ietf', 'v2', 'TCP-ESTATS-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.4.1.23.2.29.1', 'ietf', 'v1', 'TCPIPX-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.49', 'ietf', 'v2', 'TCP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.49', 'ietf', 'v2', 'TCP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.200', 'ietf', 'v2', 'TE-LINK-STD-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.122', 'ietf', 'v2', 'TE-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.3.124', 'ietf', 'v2', 'TIME-AGGREGATE-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.34.8', 'ietf', 'v2', 'TN3270E-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.34.9', 'ietf', 'v2', 'TN3270E-RT-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.9', 'ietf', 'v2', 'TOKENRING-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.9', 'ietf', 'v2', 'TOKENRING-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.16.1', 'ietf', 'v1', 'TOKEN-RING-RMON-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.42', 'ietf', 'v2', 'TOKENRING-STATION-SR-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.16.30', 'ietf', 'v2', 'TPM-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.100', 'ietf', 'v2', 'TRANSPORT-ADDRESS-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.116', 'ietf', 'v2', 'TRIP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.115', 'ietf', 'v2', 'TRIP-TC-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.131', 'ietf', 'v2', 'TUNNEL-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.131', 'ietf', 'v2', 'TUNNEL-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.170', 'ietf', 'v2', 'UDPLITE-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.50', 'ietf', 'v2', 'UDP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.50', 'ietf', 'v2', 'UDP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.33', 'ietf', 'v2', 'UPS-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.164', 'ietf', 'v2', 'URI-TC-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.229', 'ietf', 'v2', 'VDSL-LINE-EXT-MCM-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.228', 'ietf', 'v2', 'VDSL-LINE-EXT-SCM-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.10.97', 'ietf', 'v2', 'VDSL-LINE-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.129', 'ietf', 'v2', 'VPN-TC-STD-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.68', 'ietf', 'v2', 'VRRP-MIB']);
    push(@{$mibdepot}, ['1.3.6.1.2.1.65', 'ietf', 'v2', 'WWW-MIB']);
    my $oids = $self->get_entries_by_walk(-varbindlist => [
        '1.3.6.1.2.1', '1.3.6.1.4.1',
    ]);
    foreach my $mibinfo (@{$mibdepot}) {
      next if $self->opts->protocol eq "1" && $mibinfo->[2] ne "v1";
      next if $self->opts->protocol ne "1" && $mibinfo->[2] eq "v1";
      $Monitoring::GLPlugin::SNMP::MibsAndOids::mib_ids->{$mibinfo->[3]} = $mibinfo->[0];
    }
    $Monitoring::GLPlugin::SNMP::MibsAndOids::mib_ids->{'MIB-2-MIB'} = "1.3.6.1.2.1";
    foreach my $mib (keys %{$Monitoring::GLPlugin::SNMP::MibsAndOids::mib_ids}) {
      if ($self->implements_mib($mib)) {
        push(@outputlist, [$mib, $Monitoring::GLPlugin::SNMP::MibsAndOids::mib_ids->{$mib}]);
        $unknowns = {@{[map {
            $_, $self->rawdata->{$_}
        } grep {
            substr($_, 0, length($Monitoring::GLPlugin::SNMP::MibsAndOids::mib_ids->{$mib})) ne
                $Monitoring::GLPlugin::SNMP::MibsAndOids::mib_ids->{$mib} || (
            substr($_, 0, length($Monitoring::GLPlugin::SNMP::MibsAndOids::mib_ids->{$mib})) eq
                $Monitoring::GLPlugin::SNMP::MibsAndOids::mib_ids->{$mib} &&
            substr($_, length($Monitoring::GLPlugin::SNMP::MibsAndOids::mib_ids->{$mib}), 1) ne ".")
        } keys %{$unknowns}]}};
      }
    }
    my $toplevels = {};
    map {
        /^(1\.3\.6\.1\.(\d+)\.(\d+)\.\d+\.\d+)\./; $toplevels->{$1} = 1; 
    } keys %{$unknowns};
    foreach (sort {$a cmp $b} keys %{$toplevels}) {
      push(@outputlist, ["<unknown>", $_]);
    }
    foreach (sort {$a->[0] cmp $b->[0]} @outputlist) {
      printf "implements %s %s\n", $_->[0], $_->[1];
    }
    $self->add_ok("have fun");
    my ($code, $message) = $self->check_messages(join => ', ', join_all => ', ');
    $Monitoring::GLPlugin::plugin->nagios_exit($code, $message);
  }
}

sub check_snmp_and_model {
  my ($self) = @_;
  if ($self->opts->snmpwalk) {
    my $response = {};
    if (! -f $self->opts->snmpwalk) {
      $self->add_message(CRITICAL, 
          sprintf 'file %s not found',
          $self->opts->snmpwalk);
    } elsif (-x $self->opts->snmpwalk) {
      my $cmd = sprintf "%s -ObentU -v%s -c%s %s 1.3.6.1.4.1 2>&1",
          $self->opts->snmpwalk,
          $self->opts->protocol,
          $self->opts->community,
          $self->opts->hostname;
      open(WALK, "$cmd |");
      while (<WALK>) {
        if (/^([\.\d]+) = .*?: (\-*\d+)/) {
          $response->{$1} = $2;
        } elsif (/^([\.\d]+) = .*?: "(.*?)"/) {
          $response->{$1} = $2;
          $response->{$1} =~ s/\s+$//;
        }
      }
      close WALK;
    } else {
      if (defined $self->opts->offline && $self->opts->mode ne 'walk') {
        if ((time - (stat($self->opts->snmpwalk))[9]) > $self->opts->offline) {
          $self->add_message(UNKNOWN,
              sprintf 'snmpwalk file %s is too old', $self->opts->snmpwalk);
        }
      }
      $self->opts->override_opt('hostname', 'walkhost') if $self->opts->mode ne 'walk';
      open(MESS, $self->opts->snmpwalk);
      while(<MESS>) {
        # SNMPv2-SMI::enterprises.232.6.2.6.7.1.3.1.4 = INTEGER: 6
        if (/^([\d\.]+) = .*?INTEGER: .*\((\-*\d+)\)/) {
          # .1.3.6.1.2.1.2.2.1.8.1 = INTEGER: down(2)
          $response->{$1} = $2;
        } elsif (/^([\d\.]+) = .*?Opaque:.*?Float:.*?([\-\.\d]+)/) {
          # .1.3.6.1.4.1.2021.10.1.6.1 = Opaque: Float: 0.938965
          $response->{$1} = $2;
        } elsif (/^([\d\.]+) = STRING:\s*$/) {
          $response->{$1} = "";
        } elsif (/^([\d\.]+) = Network Address: (.*)/) {
          $response->{$1} = $2;
        } elsif (/^([\d\.]+) = Hex-STRING: (.*)/) {
          my $k = $1;
          my $h = $2;
          $h =~ s/\s+//g;
          $response->{$k} = pack('H*', $h);
        } elsif (/^([\d\.]+) = \w+: (\-*\d+)\s*$/) {
          $response->{$1} = $2;
        } elsif (/^([\d\.]+) = \w+: "(.*?)"/) {
          $response->{$1} = $2;
          $response->{$1} =~ s/\s+$//;
        } elsif (/^([\d\.]+) = \w+: (.*)/) {
          $response->{$1} = $2;
          $response->{$1} =~ s/\s+$//;
        } elsif (/^([\d\.]+) = (\-*\d+)/) {
          $response->{$1} = $2;
        } elsif (/^([\d\.]+) = "(.*?)"/) {
          $response->{$1} = $2;
          $response->{$1} =~ s/\s+$//;
        }
      }
      close MESS;
    }
    foreach my $oid (keys %$response) {
      if ($oid =~ /^\./) {
        my $nodot = $oid;
        $nodot =~ s/^\.//g;
        $response->{$nodot} = $response->{$oid};
        delete $response->{$oid};
      }
    }
    map { $response->{$_} =~ s/^\s+//; $response->{$_} =~ s/\s+$//; }
        keys %$response;
    $self->set_rawdata($response);
  } else {
    $self->establish_snmp_session();
  }
  if (! $self->check_messages()) {
    my $tic = time;
    my $sysUptime = $self->get_snmp_object('MIB-2-MIB', 'sysUpTime', 0);
    my $snmpEngineTime = $self->get_snmp_object('SNMP-FRAMEWORK-MIB', 'snmpEngineTime');
    my $sysDescr = $self->get_snmp_object('MIB-2-MIB', 'sysDescr', 0);
    my $tac = time;
    if (defined $sysUptime && defined $sysDescr) {
      # drecksschrott asa liefert negative werte
      # und drecksschrott socomec liefert: wrong type (should be INTEGER): NULL
      if (defined $snmpEngineTime && $snmpEngineTime =~ /^\d+$/ && $snmpEngineTime > 0) {
        $self->{uptime} = $snmpEngineTime;
      } else {
        $self->{uptime} = $self->timeticks($sysUptime);
      }
      $self->{productname} = $sysDescr;
      $self->{sysobjectid} = $self->get_snmp_object('MIB-2-MIB', 'sysObjectID', 0);
      $self->debug(sprintf 'uptime: %s', $self->{uptime});
      $self->debug(sprintf 'up since: %s',
          scalar localtime (time - $self->{uptime}));
      $Monitoring::GLPlugin::SNMP::uptime = $self->{uptime};
      $self->debug('whoami: '.$self->{productname});
    } else {
      if ($tac - $tic >= $Monitoring::GLPlugin::SNMP::session->timeout) {
        $self->add_message(UNKNOWN,
            'could not contact snmp agent, timeout during snmp-get sysUptime');
      } else {
        $self->add_message(UNKNOWN,
            'got neither sysUptime nor sysDescr, is this snmp agent working correctly?');
      }
      $Monitoring::GLPlugin::SNMP::session->close if $Monitoring::GLPlugin::SNMP::session;
    }
  }
}

sub establish_snmp_session {
  my ($self) = @_;
  $self->set_timeout_alarm();
  if (eval "require Net::SNMP") {
    my %params = ();
    my $net_snmp_version = Net::SNMP->VERSION(); # 5.002000 or 6.000000
    $params{'-translate'} = [ # because we see "NULL" coming from socomec devices
      -all => 0x0,
      -nosuchobject => 1,
      -nosuchinstance => 1,
      -endofmibview => 1,
      -unsigned => 1,
    ];
    $params{'-hostname'} = $self->opts->hostname;
    $params{'-version'} = $self->opts->protocol;
    if ($self->opts->port) {
      $params{'-port'} = $self->opts->port;
    }
    if ($self->opts->domain) {
      $params{'-domain'} = $self->opts->domain;
    }
    $self->v2tov3;
    if ($self->opts->protocol eq '3') {
      $params{'-version'} = $self->opts->protocol;
      $params{'-username'} = $self->opts->username;
      if ($self->opts->authpassword) {
        $params{'-authpassword'} = 
            $self->decode_password($self->opts->authpassword);
      }
      if ($self->opts->authprotocol) {
        $params{'-authprotocol'} = $self->opts->authprotocol;
      }
      if ($self->opts->privpassword) {
        $params{'-privpassword'} = 
            $self->decode_password($self->opts->privpassword);
      }
      if ($self->opts->privprotocol) {
        $params{'-privprotocol'} = $self->opts->privprotocol;
      }
      # context hat in der session nix verloren, sondern wird
      # als zusatzinfo bei den requests mitgeschickt
      #if ($self->opts->contextengineid) {
      #  $params{'-contextengineid'} = $self->opts->contextengineid;
      #}
      #if ($self->opts->contextname) {
      #  $params{'-contextname'} = $self->opts->contextname;
      #}
    } else {
      $params{'-community'} = 
          $self->decode_password($self->opts->community);
    }
    my ($session, $error) = Net::SNMP->session(%params);
    if (! defined $session) {
      $self->add_message(CRITICAL, 
          sprintf 'cannot create session object: %s', $error);
      $self->debug(Data::Dumper::Dumper(\%params));
    } else {
      my $max_msg_size = $session->max_msg_size();
      $session->max_msg_size(4 * $max_msg_size);
      $Monitoring::GLPlugin::SNMP::session = $session;
    }
  } else {
    $self->add_message(CRITICAL,
        'could not find Net::SNMP module');
  }
}

sub session_translate {
  my ($self, $translation) = @_;
  $Monitoring::GLPlugin::SNMP::session->translate($translation) if
      $Monitoring::GLPlugin::SNMP::session;
}

sub establish_snmp_secondary_session {
  my ($self) = @_;
  if ($self->opts->protocol eq '3') {
  } else {
    if (defined $self->opts->community2 &&
        $self->decode_password($self->opts->community2) ne
        $self->decode_password($self->opts->community)) {
      $Monitoring::GLPlugin::SNMP::session = undef;
      $self->opts->override_opt('community',
        $self->decode_password($self->opts->community2)) ;
      $self->establish_snmp_session;
    }
  }
}

sub mult_snmp_max_msg_size {
  my ($self, $factor) = @_;
  $factor ||= 10;
  $self->debug(sprintf "raise maxmsgsize %d * %d", 
      $factor, $Monitoring::GLPlugin::SNMP::session->max_msg_size()) if $Monitoring::GLPlugin::SNMP::session;
  $Monitoring::GLPlugin::SNMP::session->max_msg_size($factor * $Monitoring::GLPlugin::SNMP::session->max_msg_size()) if $Monitoring::GLPlugin::SNMP::session;
}

sub no_such_model {
  my ($self) = @_;
  printf "Model %s is not implemented\n", $self->{productname};
  exit 3;
}

sub no_such_mode {
  my ($self) = @_;
  if (ref($self) eq "Classes::Generic") {
    $self->init();
  } elsif (ref($self) eq "Classes::Device") {
    $self->add_message(UNKNOWN, 'the device did not implement the mibs this plugin is asking for');
    $self->add_message(UNKNOWN,
        sprintf('unknown device%s', $self->{productname} eq 'unknown' ?
            '' : '('.$self->{productname}.')'));
  } elsif (ref($self) eq "Monitoring::GLPlugin::SNMP") {
    # uptime, offline
    $self->init();
  } else {
    eval {
      bless $self, "Classes::Generic";
      $self->init();
    };
    if ($@) {
      bless $self, "Monitoring::GLPlugin::SNMP";
      $self->init();
    }
  }
  if (ref($self) eq "Monitoring::GLPlugin::SNMP") {
    printf "Mode %s is not implemented for this type of device\n",
        $self->opts->mode;
    exit 3;
  }
}

sub uptime {
  my ($self) = @_;
  return $Monitoring::GLPlugin::SNMP::uptime;
}

sub map_oid_to_class {
  my ($self, $oid, $class) = @_;
  $Monitoring::GLPlugin::SNMP::MibsAndOids::discover_ids->{$oid} = $class;
}

sub discover_suitable_class {
  my ($self) = @_;
  my $sysobj = $self->get_snmp_object('MIB-2-MIB', 'sysObjectID', 0);
  $sysobj =~ s/^\.//g;
  foreach my $oid (keys %{$Monitoring::GLPlugin::SNMP::MibsAndOids::discover_ids}) {
    if ($sysobj && $oid eq $sysobj) {
      return $Monitoring::GLPlugin::SNMP::MibsAndOids::discover_ids->{$sysobj};
    }
  }
}

sub require_mib {
  my ($self, $mib) = @_;
  my $package = uc $mib;
  $package =~ s/-//g;
  if (exists $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib} ||
      exists $Monitoring::GLPlugin::SNMP::MibsAndOids::mib_ids->{$mib}) {
    $self->debug("i know package "."Monitoring::GLPlugin::SNMP::MibsAndOids::".$package);
    return;
  } else {
    eval {
      my @oldkeys = ();
      $self->set_variable("verbosity", 2);
      if ($self->get_variable("verbose")) {
        my @oldkeys = exists $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib} ?
            keys %{$Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids} : 0;
      }
      $self->debug("load mib "."Monitoring::GLPlugin::SNMP::MibsAndOids::".$package);
      load "Monitoring::GLPlugin::SNMP::MibsAndOids::".$package;
      if ($self->get_variable("verbose")) {
        my @newkeys = exists $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib} ?
            keys %{$Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids} : 0;
        $self->debug(sprintf "now i know: %s", join(" ", sort @newkeys));
        $self->debug(sprintf "now i know %d keys.", scalar(@newkeys));
        if (scalar(@newkeys) <= scalar(@oldkeys)) {
          $self->debug(sprintf "from %d to %d keys. why did we load?",
              scalar(@oldkeys), scalar(@newkeys));
        }
      }
    };
    if ($@) {
      $self->debug("failed to load "."Monitoring::GLPlugin::SNMP::MibsAndOids::".$package);
    } else {
      if (exists $Monitoring::GLPlugin::SNMP::MibsAndOids::requirements->{$mib}) {
        foreach my $submib (@{$Monitoring::GLPlugin::SNMP::MibsAndOids::requirements->{$mib}}) {
          $self->require_mib($submib);
        }
      }
    }
  }
}

sub implements_mib {
  my ($self, $mib) = @_;
  $self->require_mib($mib);
  if (! exists $Monitoring::GLPlugin::SNMP::MibsAndOids::mib_ids->{$mib}) {
    return 0;
  }
  my $sysobj = $self->get_snmp_object('MIB-2-MIB', 'sysObjectID', 0);
  $sysobj =~ s/^\.// if $sysobj;
  if ($sysobj && $sysobj eq $Monitoring::GLPlugin::SNMP::MibsAndOids::mib_ids->{$mib}) {
    $self->debug(sprintf "implements %s (sysobj exact)", $mib);
    return 1;
  }
  if ($sysobj && $Monitoring::GLPlugin::SNMP::MibsAndOids::mib_ids->{$mib} eq
      substr $sysobj, 0, length $Monitoring::GLPlugin::SNMP::MibsAndOids::mib_ids->{$mib}) {
    $self->debug(sprintf "implements %s (sysobj)", $mib);
    return 1;
  }
  # some mibs are only composed of tables
  my $traces;
  if ($self->opts->snmpwalk) {
    my @matches;  
    # exact match  
    push(@matches, @{[map {  
        $_, $self->rawdata->{$_}  
    } grep {  
        $_ eq $Monitoring::GLPlugin::SNMP::MibsAndOids::mib_ids->{$mib}  
    } keys %{$self->rawdata}]});  
  
    # partial match (add trailing dot)  
    my $check = $Monitoring::GLPlugin::SNMP::MibsAndOids::mib_ids->{$mib};  
    $check =~ s/\.?$/./;  
    push(@matches, @{[map {  
        $_, $self->rawdata->{$_}  
    } grep {
        substr($_, 0, length($check)) eq $check  
    } keys %{$self->rawdata}]});  
    $traces = {@matches};  
  } else {
    my %params = (
        -varbindlist => [
            $Monitoring::GLPlugin::SNMP::MibsAndOids::mib_ids->{$mib}
        ]
    );
    if ($Monitoring::GLPlugin::SNMP::session->version() == 3) {
      $params{-contextengineid} = $self->opts->contextengineid if $self->opts->contextengineid;
      $params{-contextname} = $self->opts->contextname if $self->opts->contextname;
    }
    $traces = $Monitoring::GLPlugin::SNMP::session->get_next_request(%params);
  }
  if ($traces && # must find oids following to the ident-oid
      ! exists $traces->{$Monitoring::GLPlugin::SNMP::MibsAndOids::mib_ids->{$mib}} && # must not be the ident-oid
      grep { # following oid is inside this tree
          substr($_, 0, length($Monitoring::GLPlugin::SNMP::MibsAndOids::mib_ids->{$mib})) eq $Monitoring::GLPlugin::SNMP::MibsAndOids::mib_ids->{$mib};
      } keys %{$traces}) {
    $self->debug(sprintf "implements %s (found traces)", $mib);
    return 1;
  }
}

sub timeticks {
  my ($self, $timestr) = @_;
  if ($timestr =~ /\((\d+)\)/) {
    # Timeticks: (20718727) 2 days, 9:33:07.27
    $timestr = $1 / 100;
  } elsif ($timestr =~ /(\d+)\s*day[s]*.*?(\d+):(\d+):(\d+)\.(\d+)/) {
    # Timeticks: 2 days, 9:33:07.27
    $timestr = $1 * 24 * 3600 + $2 * 3600 + $3 * 60 + $4;
  } elsif ($timestr =~ /(\d+):(\d+):(\d+):(\d+)\.(\d+)/) {
    # Timeticks: 0001:03:18:42.77
    $timestr = $1 * 3600 * 24 + $2 * 3600 + $3 * 60 + $4;
  } elsif ($timestr =~ /(\d+):(\d+):(\d+)\.(\d+)/) {
    # Timeticks: 9:33:07.27
    $timestr = $1 * 3600 + $2 * 60 + $3;
  } elsif ($timestr =~ /(\d+)\s*hour[s]*.*?(\d+):(\d+)\.(\d+)/) {
    # Timeticks: 3 hours, 42:17.98
    $timestr = $1 * 3600 + $2 * 60 + $3;
  } elsif ($timestr =~ /(\d+)\s*minute[s]*.*?(\d+)\.(\d+)/) {
    # Timeticks: 36 minutes, 01.96
    $timestr = $1 * 60 + $2;
  } elsif ($timestr =~ /(\d+)\.\d+\s*second[s]/) {
    # Timeticks: 01.02 seconds
    $timestr = $1;
  } elsif ($timestr =~ /^(\d+)$/) {
    $timestr = $1 / 100;
  }
  return $timestr;
}

sub human_timeticks {
  my ($self, $timeticks) = @_;
  my $days = int($timeticks / 86400);
  $timeticks -= ($days * 86400);
  my $hours = int($timeticks / 3600);
  $timeticks -= ($hours * 3600);
  my $minutes = int($timeticks / 60);
  my $seconds = $timeticks % 60;
  $days = $days < 1 ? '' : $days .'d ';
  return $days . sprintf "%dh %dm %ds", $hours, $minutes, $seconds;
}

sub internal_name {
  my ($self) = @_;
  my $class = ref($self);
  $class =~ s/^.*:://;
  if (exists $self->{flat_indices}) {
    return sprintf "%s_%s", uc $class, $self->{flat_indices};
  } else {
    return sprintf "%s", uc $class;
  }
}

################################################################
# file-related functions
#
sub create_interface_cache_file {
  my ($self) = @_;
  my $extension = "";
  if ($self->opts->snmpwalk && ! $self->opts->hostname) {
    $self->opts->override_opt('hostname',
        'snmpwalk.file'.md5_hex($self->opts->snmpwalk))
  }
  if ($self->opts->community) { 
    $extension .= md5_hex($self->opts->community);
  }
  $extension =~ s/\//_/g;
  $extension =~ s/\(/_/g;
  $extension =~ s/\)/_/g;
  $extension =~ s/\*/_/g;
  $extension =~ s/\s/_/g;
  return sprintf "%s/%s_interface_cache_%s", $self->statefilesdir(),
      $self->opts->hostname, lc $extension;
}

sub create_entry_cache_file {
  my ($self, $mib, $table, $key_attr) = @_;
  return lc sprintf "%s_%s_%s_%s_cache",
      $self->create_interface_cache_file(),
      $mib, $table, join('#', @{$key_attr});
}

sub update_entry_cache {
  my ($self, $force, $mib, $table, $key_attr) = @_;
  if (ref($key_attr) ne "ARRAY") {
    $key_attr = [$key_attr];
  }
  my $cache = sprintf "%s_%s_%s_cache", 
      $mib, $table, join('#', @{$key_attr});
  my $statefile = $self->create_entry_cache_file($mib, $table, $key_attr);
  my $update = time - 3600;
  #my $update = time - 1;
  if ($force || ! -f $statefile || ((stat $statefile)[9]) < ($update)) {
    $self->debug(sprintf 'force update of %s %s %s %s cache',
        $self->opts->hostname, $self->opts->mode, $mib, $table);
    $self->{$cache} = {};
    foreach my $entry ($self->get_snmp_table_objects($mib, $table)) {
      my $key = join('#', map { $entry->{$_} } @{$key_attr});
      my $hash = $key . '-//-' . join('.', @{$entry->{indices}});
      $self->{$cache}->{$hash} = $entry->{indices};
    }
    $self->save_cache($mib, $table, $key_attr);
  }
  $self->load_cache($mib, $table, $key_attr);
}

sub save_cache {
  my ($self, $mib, $table, $key_attr) = @_;
  if (ref($key_attr) ne "ARRAY") {
    $key_attr = [$key_attr];
  }
  my $cache = sprintf "%s_%s_%s_cache", 
      $mib, $table, join('#', @{$key_attr});
  $self->create_statefilesdir();
  my $statefile = $self->create_entry_cache_file($mib, $table, $key_attr);
  open(STATE, ">".$statefile.".".$$);
  printf STATE Data::Dumper::Dumper($self->{$cache});
  close STATE;
  rename $statefile.".".$$, $statefile;
  $self->debug(sprintf "saved %s to %s",
      Data::Dumper::Dumper($self->{$cache}), $statefile);
}

sub load_cache {
  my ($self, $mib, $table, $key_attr) = @_;
  if (ref($key_attr) ne "ARRAY") {
    $key_attr = [$key_attr];
  }
  my $cache = sprintf "%s_%s_%s_cache", 
      $mib, $table, join('#', @{$key_attr});
  my $statefile = $self->create_entry_cache_file($mib, $table, $key_attr);
  $self->{$cache} = {};
  if ( -f $statefile) {
    our $VAR1;
    our $VAR2;
    eval {
      require $statefile;
    };
    if($@) {
      printf "rumms\n";
    }
    # keinesfalls mehr require verwenden!!!!!!
    # beim require enthaelt VAR1 andere werte als beim slurp
    # und zwar diejenigen, die beim letzten save_cache geschrieben wurden.
    my $content = do { local (@ARGV, $/) = $statefile; my $x = <>; close ARGV; $x };
    $VAR1 = eval "$content";
    $self->debug(sprintf "load %s", Data::Dumper::Dumper($VAR1));
    $self->{$cache} = $VAR1;
  }
}


################################################################
# top-level convenience functions
#
sub get_snmp_objects {
  my ($self, $mib, @mos) = @_;
  foreach (@mos) {
    #my $value = $self->get_snmp_object($mib, $_, 0);
    #if (defined $value) {
    #  $self->{$_} = $value;
    #} else {
      my $value = $self->get_snmp_object($mib, $_);
      if (defined $value) {
        $self->{$_} = $value;
      }
    #}
  }
}

sub get_snmp_tables {
  my ($self, $mib, $infos) = @_;
  foreach my $info (@{$infos}) {
    my $arrayname = $info->[0];
    my $table = $info->[1];
    my $class = $info->[2];
    my $filter = $info->[3];
    my $rows = $info->[4];
    $self->{$arrayname} = [] if ! exists $self->{$arrayname};
    if (! exists $Monitoring::GLPlugin::SNMP::tablecache->{$mib} || ! exists $Monitoring::GLPlugin::SNMP::tablecache->{$mib}->{$table}) {
      $Monitoring::GLPlugin::SNMP::tablecache->{$mib}->{$table} = [];
      foreach ($self->get_snmp_table_objects($mib, $table, undef, $rows)) {
        push(@{$Monitoring::GLPlugin::SNMP::tablecache->{$mib}->{$table}}, $_);
        my $new_object = $class->new(%{$_});
        next if (defined $filter && ! &$filter($new_object));
        push(@{$self->{$arrayname}}, $new_object);
      }
    } else {
      $self->debug(sprintf "get_snmp_tables %s %s cache hit", $mib, $table);
      foreach (@{$Monitoring::GLPlugin::SNMP::tablecache->{$mib}->{$table}}) {
        my $new_object = $class->new(%{$_});
        next if (defined $filter && ! &$filter($new_object));
        push(@{$self->{$arrayname}}, $new_object);
      }
    }
  }
}

sub merge_tables {
  my ($self, $into, @from) = @_;
  my $into_indices = {};
  map { $into_indices->{$_->{flat_indices}} = $_ } @{$self->{$into}};
  foreach (@from) {
    foreach my $element (@{$self->{$_}}) {
      if (exists $into_indices->{$element->{flat_indices}}) {
        foreach my $key (keys %{$element}) {
          $into_indices->{$element->{flat_indices}}->{$key} = $element->{$key};
        }
      }
    }
    delete $self->{$_};
  }
}

sub merge_tables_with_code {
  my ($self, $into, @from) = @_;
  my $into_indices = {};
  my @to_del = ();
  foreach my $into_elem (@{$self->{$into}}) {
    for (my $i = 0; $i < @from; $i += 2) {
      my ($from_elems, $func) = @from[$i, $i+1];
      foreach my $from_elem (@{$self->{$from_elems}}) {
        if (&$func($into_elem, $from_elem)) {
          foreach my $key (grep !/^(info|trace|warning|critical|blacklisted|extendedinfo|flat_indices|indices)/, sort keys %{$from_elem}) {
            $into_elem->{$key} = $from_elem->{$key};
          }
        }
      }
    }
  }
  for (my $i = 0; $i < @from; $i += 2) {
    my ($from_elems, $func) = @from[$i, $i+1];
    delete $self->{$from_elems};
  }
}

sub mibs_and_oids_definition {
  my ($self, $mib, $definition, @values) = @_;
  if (exists $Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{$mib} &&
      exists $Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{$mib}->{$definition}) {
    if (ref($Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{$mib}->{$definition}) eq "CODE") {
      return $Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{$mib}->{$definition}->(@values);
    } elsif (ref($Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{$mib}->{$definition}) eq "HASH") {
      return $Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{$mib}->{$definition}->{$values[0]};
    }
  } else {
    return "unknown_".$definition;
  }
}

sub clear_table_cache {
  my ($self, $mib, $table) = @_;
  if ($table && exists $Monitoring::GLPlugin::SNMP::tablecache->{$mib}) {
    delete $Monitoring::GLPlugin::SNMP::tablecache->{$mib}->{$table};
  } elsif ($mib) {
    delete $Monitoring::GLPlugin::SNMP::tablecache->{$mib};
  } else {
    $Monitoring::GLPlugin::SNMP::tablecache = {};
  }
}

################################################################
# 2nd level 
#
sub get_snmp_object {
  my ($self, $mib, $mo, $index) = @_;
  $self->require_mib($mib);
  if (exists $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib} &&
      exists $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$mo}) {
    my $oid = $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$mo}.
        (defined $index ? '.'.$index : '');
    my $response = $self->get_request(-varbindlist => [$oid]);
    if (defined $response->{$oid}) {
      if ($response->{$oid} eq 'noSuchInstance' || $response->{$oid} eq 'noSuchObject') {
        $response->{$oid} = undef;
      } elsif (my @symbols = $self->make_symbolic($mib, $response, [[$index]])) {
        $response->{$oid} = $symbols[0]->{$mo};
      }
    }
    $self->debug(sprintf "GET: %s::%s (%s) : %s", $mib, $mo, $oid, defined $response->{$oid} ? $response->{$oid} : "<undef>");
    if (! defined $response->{$oid} && ! defined $index) {
      return $self->get_snmp_object($mib, $mo, 0);
    }
    return $response->{$oid};
  }
  return undef;
}

sub get_snmp_table_objects_with_cache {
  my ($self, $mib, $table, $key_attr) = @_;
  #return $self->get_snmp_table_objects($mib, $table);
  $self->update_entry_cache(0, $mib, $table, $key_attr);
  my @indices = $self->get_cache_indices($mib, $table, $key_attr);
  my @entries = ();
  foreach ($self->get_snmp_table_objects($mib, $table, \@indices)) {
    push(@entries, $_);
  }
  return @entries;
}

sub get_table_row_oids {
  my ($self, $mib, $table, $rows) = @_;
  $self->require_mib($mib);
  my $entry = $table;
  $entry =~ s/Table/Entry/g;
  my $eoid = $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$entry}.'.';
  my $eoidlen = length($eoid);
  my @columns = scalar(@{$rows}) ?
  map {
      $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$_}
  } @{$rows}
  :
  map {
      $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$_}
  } grep {
    substr($Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$_}, 0, $eoidlen) eq
        $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$entry}.'.'
  } keys %{$Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}};
  return @columns;
}

# get_snmp_table_objects('MIB-Name', 'Table-Name', 'Table-Entry', [indices])
# returns array of hashrefs
sub get_snmp_table_objects {
  my ($self, $mib, $table, $indices, $rows) = @_;
  $indices ||= [];
  $rows ||= [];
  $self->require_mib($mib);
  my @entries = ();
  my $augmenting_table;
  $self->debug(sprintf "get_snmp_table_objects %s %s", $mib, $table);
  if ($table =~ /^(.*?)\+(.*)/) {
    $table = $1;
    $augmenting_table = $2;
  }
  my $entry = $table;
  $entry =~ s/Table/Entry/g;
  if (exists $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib} &&
      exists $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$table}) {
    if (scalar(@{$indices}) == 1 && $indices->[0] == -1) {
      # get mini-version of a table
      my $result = {};
      my $eoid = $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$entry}.'.';
      my $eoidlen = length($eoid);
      my @columns = map {
          $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$_}
      } grep {
        substr($Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$_}, 0, $eoidlen) eq
            $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$entry}.'.'
      } keys %{$Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}};
      my $ifresult = $self->get_entries(
          -columns => \@columns,
      );
      map { $result->{$_} = $ifresult->{$_} }
          keys %{$ifresult};
      if ($augmenting_table &&
          exists $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$augmenting_table}) {
        my $entry = $augmenting_table;
        $entry =~ s/Table/Entry/g;
        my $eoid = $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$entry}.'.';
        my $eoidlen = length($eoid);
        my @columns = map {
            $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$_}
        } grep {
          substr($Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$_}, 0, $eoidlen) eq $eoid
        } keys %{$Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}};
        my $ifresult = $self->get_entries(
            -columns => \@columns,
        );
        map { $result->{$_} = $ifresult->{$_} }
            keys %{$ifresult};
      }
      my @indices = 
          $self->get_indices(
              -baseoid => $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$entry},
              -oids => [keys %{$result}]);
      $self->debug(sprintf "get_snmp_table_objects get_table returns %d indices",
          scalar(@indices));
      @entries = $self->make_symbolic($mib, $result, \@indices);
      @entries = map { $_->{indices} = shift @indices; $_ } @entries;
    } elsif (scalar(@{$indices}) == 1) {
      my $result = {};
      my $eoid = $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$entry}.'.';
      my $eoidlen = length($eoid);
      my @columns = map {
          $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$_}
      } grep {
        substr($Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$_}, 0, $eoidlen) eq
            $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$entry}.'.'
      } keys %{$Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}};
      my $index = join('.', @{$indices->[0]});
      my $ifresult = $self->get_entries(
          -startindex => $index,
          -endindex => $index,
          -columns => \@columns,
      );
      map { $result->{$_} = $ifresult->{$_} }
          keys %{$ifresult};
      if ($augmenting_table &&
          exists $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$augmenting_table}) {
        my $entry = $augmenting_table;
        $entry =~ s/Table/Entry/g;
        my $eoid = $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$entry}.'.';
        my $eoidlen = length($eoid);
        my @columns = map {
            $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$_}
        } grep {
          substr($Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$_}, 0, $eoidlen) eq $eoid
        } keys %{$Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}};
        my $ifresult = $self->get_entries(
            -startindex => $index,
            -endindex => $index,
            -columns => \@columns,
        );
        map { $result->{$_} = $ifresult->{$_} }
            keys %{$ifresult};
      }
      @entries = $self->make_symbolic($mib, $result, $indices);
      @entries = map { $_->{indices} = shift @{$indices}; $_ } @entries;
    } elsif (scalar(@{$indices}) > 1) {
    # man koennte hier pruefen, ob die indices aufeinanderfolgen
    # und dann get_entries statt get_table aufrufen
      my $result = {};
      my $eoid = $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$entry}.'.';
      my $eoidlen = length($eoid);
      my @columns = map {
          $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$_}
      } grep {
        substr($Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$_}, 0, $eoidlen) eq $eoid
      } keys %{$Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}};
      my @sortedindices = map { $_->[0] }
          sort { $a->[1] cmp $b->[1] }
              map { [$_,
                  join '', map { sprintf("%30d",$_) } split( /\./, $_)
              ] } map { join('.', @{$_})} @{$indices};
      my $startindex = $sortedindices[0];
      my $endindex = $sortedindices[$#sortedindices];
      if (0) {
        # holzweg. dicke ciscos liefern unvollstaendiges resultat, d.h.
        # bei 138,19,157 kommt nur 138..144, dann ist schluss.
        # maxrepetitions bringt nichts.
        $result = $self->get_entries(
            -startindex => $startindex,
            -endindex => $endindex,
            -columns => \@columns,
        );
      } else {
        foreach my $ifidx (@sortedindices) {
          my $ifresult = $self->get_entries(
              -startindex => $ifidx,
              -endindex => $ifidx,
              -columns => \@columns,
          );
          map { $result->{$_} = $ifresult->{$_} }
              keys %{$ifresult};
        }
      }
      if ($augmenting_table &&
          exists $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$augmenting_table}) {
        my $entry = $augmenting_table;
        $entry =~ s/Table/Entry/g;
        my $eoid = $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$entry}.'.';
        my $eoidlen = length($eoid);
        my @columns = map {
            $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$_}
        } grep {
          substr($Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$_}, 0, $eoidlen) eq $eoid
        } keys %{$Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}};
        foreach my $ifidx (@sortedindices) {
          my $ifresult = $self->get_entries(
              -startindex => $ifidx,
              -endindex => $ifidx,
              -columns => \@columns,
          );
          map { $result->{$_} = $ifresult->{$_} }
              keys %{$ifresult};
        }
      }
      # now we have numerical_oid+index => value
      # needs to become symboic_oid => value
      #my @indices =
      # $self->get_indices($Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$entry});
      @entries = $self->make_symbolic($mib, $result, $indices);
      @entries = map { $_->{indices} = shift @{$indices}; $_ } @entries;
    } elsif (scalar(@{$rows})) {
      my @columns = $self->get_table_row_oids($mib, $table, $rows);
      my $result = $self->get_entries(
          -columns => \@columns,
      );
      $self->debug(sprintf "get_snmp_table_objects get_table_r returns %d oids",
          scalar(keys %{$result}));
      my @indices =
          $self->get_indices(
              -baseoid => $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$entry},
              -oids => [keys %{$result}]);
      $self->debug(sprintf "get_snmp_table_objects get_table_r returns %d indices",
          scalar(@indices));
      @entries = $self->make_symbolic($mib, $result, \@indices);
      @entries = map { $_->{indices} = shift @indices; $_ } @entries;
    } else {
      $self->debug(sprintf "get_snmp_table_objects calls get_table %s",
          $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$table});
      my $result = $self->get_table(
          -baseoid => $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$table});
      $self->debug(sprintf "get_snmp_table_objects get_table returns %d oids",
          scalar(keys %{$result}));
      # now we have numerical_oid+index => value
      # needs to become symboic_oid => value
      my @indices = 
          $self->get_indices(
              -baseoid => $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$entry},
              -oids => [keys %{$result}]);
      $self->debug(sprintf "get_snmp_table_objects get_table returns %d indices",
          scalar(@indices));
      @entries = $self->make_symbolic($mib, $result, \@indices);
      @entries = map { $_->{indices} = shift @indices; $_ } @entries;
    }
  }
  @entries = map { $_->{flat_indices} = join(".", @{$_->{indices}}); $_ } @entries;
  return @entries;
}

################################################################
# 3rd level functions. calling net::snmp-functions
# 
sub get_request {
  my ($self, %params) = @_;
  my @notcached = ();
  foreach my $oid (@{$params{'-varbindlist'}}) {
    $self->add_oidtrace($oid);
    if (! exists $Monitoring::GLPlugin::SNMP::rawdata->{$oid}) {
      push(@notcached, $oid);
    }
  }
  if (! $self->opts->snmpwalk && (scalar(@notcached) > 0)) {
    my %params = ();
    if ($Monitoring::GLPlugin::SNMP::session->version() == 0) {
      $params{-varbindlist} = \@notcached;
    } elsif ($Monitoring::GLPlugin::SNMP::session->version() == 1) {
      $params{-varbindlist} = \@notcached;
      #$params{-nonrepeaters} = scalar(@notcached);
    } elsif ($Monitoring::GLPlugin::SNMP::session->version() == 3) {
      $params{-varbindlist} = \@notcached;
      $params{-contextengineid} = $self->opts->contextengineid if $self->opts->contextengineid;
      $params{-contextname} = $self->opts->contextname if $self->opts->contextname;
    }
    my $result = $Monitoring::GLPlugin::SNMP::session->get_request(%params);
    # so, und jetzt gibts stinkstiefel, die kriegen
    # params{-varbindlist => [1.3.6.1.4.1.318.1.1.1.1.1.1]
    # und result ist
    # { 1.3.6.1.4.1.318.1.1.1.1.1.1.0 => "Smart-UPS RT 10000 XL" }
    # letzteres kommt in raw_data
    # und beim abschliessenden map wirds natuerlich nicht mehr gefunden 
    # also leeres return. <<kraftausdruck>>
    foreach my $key (%{$result}) {
      $self->add_rawdata($key, $result->{$key});
    }
  }
  my $result = {};
  map {
      $result->{$_} = exists $Monitoring::GLPlugin::SNMP::rawdata->{$_} ?
          $Monitoring::GLPlugin::SNMP::rawdata->{$_} :
      exists $Monitoring::GLPlugin::SNMP::rawdata->{$_.'.0'} ?
          $Monitoring::GLPlugin::SNMP::rawdata->{$_.'.0'} : undef;
  } @{$params{'-varbindlist'}};
  return $result;
}

sub get_entries_get_bulk {
  my ($self, %params) = @_;
  my $result = {};
  $self->debug(sprintf "get_entries_get_bulk %s", Data::Dumper::Dumper(\%params));
  my %newparams = ();
  $newparams{'-maxrepetitions'} = 3;
  $newparams{'-startindex'} = $params{'-startindex'}
      if defined $params{'-startindex'};
  $newparams{'-endindex'} = $params{'-endindex'}
      if defined $params{'-endindex'};
  $newparams{'-columns'} = $params{'-columns'};
  if ($Monitoring::GLPlugin::SNMP::session->version() == 3) {
    $newparams{-contextengineid} = $self->opts->contextengineid if $self->opts->contextengineid;
    $newparams{-contextname} = $self->opts->contextname if $self->opts->contextname;
  }
  $result = $Monitoring::GLPlugin::SNMP::session->get_entries(%newparams);
  return $result;
}

sub get_entries_get_next {
  my ($self, %params) = @_;
  my $result = {};
  $self->debug(sprintf "get_entries_get_next %s", Data::Dumper::Dumper(\%params));
  my %newparams = ();
  $newparams{'-maxrepetitions'} = 0;
  $newparams{'-startindex'} = $params{'-startindex'}
      if defined $params{'-startindex'};
  $newparams{'-endindex'} = $params{'-endindex'}
      if defined $params{'-endindex'};
  $newparams{'-columns'} = $params{'-columns'};
  if ($Monitoring::GLPlugin::SNMP::session->version() == 3) {
    $newparams{-contextengineid} = $self->opts->contextengineid if $self->opts->contextengineid;
    $newparams{-contextname} = $self->opts->contextname if $self->opts->contextname;
  }
  $result = $Monitoring::GLPlugin::SNMP::session->get_entries(%newparams);
  return $result;
}

sub get_entries_get_next_1index {
  my ($self, %params) = @_;
  my $result = {};
  $self->debug(sprintf "get_entries_get_next_1index %s", Data::Dumper::Dumper(\%params));
  my %newparams = ();
  $newparams{'-startindex'} = $params{'-startindex'}
      if defined $params{'-startindex'};
  $newparams{'-endindex'} = $params{'-endindex'}
      if defined $params{'-endindex'};
  $newparams{'-columns'} = $params{'-columns'};
  my %singleparams = ();
  $singleparams{'-maxrepetitions'} = 0;
  if ($Monitoring::GLPlugin::SNMP::session->version() == 3) {
    $singleparams{-contextengineid} = $self->opts->contextengineid if $self->opts->contextengineid;
    $singleparams{-contextname} = $self->opts->contextname if $self->opts->contextname;
  }
  foreach my $index ($newparams{'-startindex'}..$newparams{'-endindex'}) {
    foreach my $oid (@{$newparams{'-columns'}}) {
      $singleparams{'-columns'} = [$oid];
      $singleparams{'-startindex'} = $index;
      $singleparams{'-endindex'} =$index;
      my $singleresult = $Monitoring::GLPlugin::SNMP::session->get_entries(%singleparams);
      foreach my $key (keys %{$singleresult}) {
        $result->{$key} = $singleresult->{$key};
      }
    }
  }
  return $result;
}

sub get_entries_get_simple {
  my ($self, %params) = @_;
  my $result = {};
  $self->debug(sprintf "get_entries_get_simple %s", Data::Dumper::Dumper(\%params));
  my %newparams = ();
  $newparams{'-startindex'} = $params{'-startindex'}
      if defined $params{'-startindex'};
  $newparams{'-endindex'} = $params{'-endindex'}
      if defined $params{'-endindex'};
  $newparams{'-columns'} = $params{'-columns'};
  my %singleparams = ();
  if ($Monitoring::GLPlugin::SNMP::session->version() == 3) {
    $singleparams{-contextengineid} = $self->opts->contextengineid if $self->opts->contextengineid;
    $singleparams{-contextname} = $self->opts->contextname if $self->opts->contextname;
  }
  foreach my $index ($newparams{'-startindex'}..$newparams{'-endindex'}) {
    foreach my $oid (@{$newparams{'-columns'}}) {
      $singleparams{'-varbindlist'} = [$oid.".".$index];
      my $singleresult = $Monitoring::GLPlugin::SNMP::session->get_request(%singleparams);
      foreach my $key (keys %{$singleresult}) {
        $result->{$key} = $singleresult->{$key};
      }
    }
  }
  return $result;
}

sub get_entries {
  my ($self, %params) = @_;
  # [-startindex]
  # [-endindex]
  # -columns
  my $result = {};
  $self->debug(sprintf "get_entries %s", Data::Dumper::Dumper(\%params));
  if (! $self->opts->snmpwalk) {
    $result = $self->get_entries_get_bulk(%params);
    if (! $result) {
      if (scalar (@{$params{'-columns'}}) < 50 && $params{'-endindex'} && $params{'-startindex'} eq $params{'-endindex'}) {
        $result = $self->get_entries_get_simple(%params);
      } else {
        $result = $self->get_entries_get_next(%params);
      }
      if (! $result && defined $params{'-startindex'} && $params{'-startindex'} !~ /\./) {
        # compound indexes cannot continue, as these two methods iterate numerically
        if ($Monitoring::GLPlugin::SNMP::session->error() =~ /tooBig/i) {
          $result = $self->get_entries_get_next_1index(%params);
        }
        if (! $result) {
          $result = $self->get_entries_get_simple(%params);
        }
        if (! $result) {
          $self->debug(sprintf "nutzt nix\n");
        }
      }
    }
    foreach my $key (keys %{$result}) {
      if (substr($key, -1) eq " ") {
        my $value = $result->{$key};
        delete $result->{$key};
        $key =~ s/\s+$//g;
        $result->{$key} = $value;
        #
        # warum?
        #
        # %newparams ist:
        #  '-columns' => [
        #                  '1.3.6.1.2.1.2.2.1.8',
        #                  '1.3.6.1.2.1.2.2.1.13',
        #                  ...
        #                  '1.3.6.1.2.1.2.2.1.16'
        #                ],
        #  '-startindex' => '2',
        #  '-endindex' => '2'
        #
        # und $result ist:
        #  ...
        #  '1.3.6.1.2.1.2.2.1.2.2' => 'Adaptive Security Appliance \'outside\' interface',
        #  '1.3.6.1.2.1.2.2.1.16.2 ' => 4281465004,
        #  '1.3.6.1.2.1.2.2.1.13.2' => 0,
        #  ...
        #
        # stinkstiefel!
        #
      }
      $self->add_rawdata($key, $result->{$key});
    }
  } else {
    my $preresult = $self->get_matching_oids(
        -columns => $params{'-columns'});
    foreach (keys %{$preresult}) {
      $result->{$_} = $preresult->{$_};
    }
    my @sortedkeys = map { $_->[0] }
        sort { $a->[1] cmp $b->[1] }
            map { [$_,
                    join '', map { sprintf("%30d",$_) } split( /\./, $_)
                  ] } keys %{$result};
    my @to_del = ();
    if ($params{'-startindex'}) {
      foreach my $resoid (@sortedkeys) {
        foreach my $oid (@{$params{'-columns'}}) {
          my $poid = $oid.'.';
          my $lpoid = length($poid);
          if (substr($resoid, 0, $lpoid) eq $poid) {
            my $oidpattern = $poid;
            $oidpattern =~ s/\./\\./g;
            if ($resoid =~ /^$oidpattern(.+)$/) {
              if ($1 lt $params{'-startindex'}) {
                push(@to_del, $oid.'.'.$1);
              }
            }
          }
        }
      }
    }
    if ($params{'-endindex'}) {
      foreach my $resoid (@sortedkeys) {
        foreach my $oid (@{$params{'-columns'}}) {
          my $poid = $oid.'.';
          my $lpoid = length($poid);
          if (substr($resoid, 0, $lpoid) eq $poid) {
            my $oidpattern = $poid;
            $oidpattern =~ s/\./\\./g;
            if ($resoid =~ /^$oidpattern(.+)$/) {
              if ($1 gt $params{'-endindex'}) {
                push(@to_del, $oid.'.'.$1);
              }
            }
          }
        }
      }
    }
    foreach (@to_del) {
      delete $result->{$_};
    }
  }
  return $result;
}

sub get_entries_by_walk {
  my ($self, %params) = @_;
  if (! $self->opts->snmpwalk) {
    $self->add_ok("if you get this crap working correctly, let me know");
    if ($Monitoring::GLPlugin::SNMP::session->version() == 3) {
      $params{-contextengineid} = $self->opts->contextengineid if $self->opts->contextengineid;
      $params{-contextname} = $self->opts->contextname if $self->opts->contextname;
    }
    $self->debug(sprintf "get_tree %s", Data::Dumper::Dumper(\%params));
    my @baseoids = @{$params{-varbindlist}};
    delete $params{-varbindlist};
    if ($Monitoring::GLPlugin::SNMP::session->version() == 0) {
      foreach my $baseoid (@baseoids) {
        $params{-varbindlist} = [$baseoid];
        while (my $result = $Monitoring::GLPlugin::SNMP::session->get_next_request(%params)) {
          $params{-varbindlist} = [($Monitoring::GLPlugin::SNMP::session->var_bind_names)[0]];
        }
      }
    } else {
      $params{-maxrepetitions} = 200;
      foreach my $baseoid (@baseoids) {
        $params{-varbindlist} = [$baseoid];
        while (my $result = $Monitoring::GLPlugin::SNMP::session->get_bulk_request(%params)) {
          my @names = $Monitoring::GLPlugin::SNMP::session->var_bind_names();
          my @oids = $self->sort_oids(\@names);
          $params{-varbindlist} = [pop @oids];
        }
      }
    }
  } else {
    return $self->get_matching_oids(
        -columns => $params{-varbindlist});
  }
}

sub get_table {
  my ($self, %params) = @_;
  $self->add_oidtrace($params{'-baseoid'});
  if (! $self->opts->snmpwalk) {
    my @notcached = ();
    if ($Monitoring::GLPlugin::SNMP::session->version() == 3) {
      $params{-contextengineid} = $self->opts->contextengineid if $self->opts->contextengineid;
      $params{-contextname} = $self->opts->contextname if $self->opts->contextname;
    }
    $self->debug(sprintf "get_table %s", Data::Dumper::Dumper(\%params));
    my $result = $Monitoring::GLPlugin::SNMP::session->get_table(%params);
    $self->debug(sprintf "get_table returned %d oids", scalar(keys %{$result}));
    if (scalar(keys %{$result}) == 0) {
      $self->debug(sprintf "get_table error: %s", 
          $Monitoring::GLPlugin::SNMP::session->error());
      $self->debug("get_table error: try fallback");
      $params{'-maxrepetitions'} = 1;
      $self->debug(sprintf "get_table %s", Data::Dumper::Dumper(\%params));
      $result = $Monitoring::GLPlugin::SNMP::session->get_table(%params);
      $self->debug(sprintf "get_table returned %d oids", scalar(keys %{$result}));
      if (scalar(keys %{$result}) == 0) {
        $self->debug(sprintf "get_table error: %s", 
            $Monitoring::GLPlugin::SNMP::session->error());
        $self->debug("get_table error: no more fallbacks. Try --protocol 1");
      }
    }
    # Drecksstinkstiefel Net::SNMP
    # '1.3.6.1.2.1.2.2.1.22.4 ' => 'endOfMibView',
    # '1.3.6.1.2.1.2.2.1.22.4' => '0.0',
    foreach my $key (keys %{$result}) {
      if (substr($key, -1) eq " ") {
        my $value = $result->{$key};
        delete $result->{$key};
        (my $shortkey = $key) =~ s/\s+$//g;
        if (! exists $result->{shortkey}) {
          $result->{$shortkey} = $value;
        }
        $self->add_rawdata($key, $result->{$key}) if exists $result->{$key};
      } else {
        $self->add_rawdata($key, $result->{$key});
      }
    }
  }
  return $self->get_matching_oids(
      -columns => [$params{'-baseoid'}]);
}

################################################################
# helper functions
# 
sub valid_response {
  my ($self, $mib, $oid, $index) = @_;
  $self->require_mib($mib);
  if (exists $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib} &&
      exists $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$oid}) {
    # make it numerical
    my $oid = $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$oid};
    if (defined $index) {
      $oid .= '.'.$index;
    }
    my $result = $self->get_request(
        -varbindlist => [$oid]
    );
    if (!defined($result) ||
        ! defined $result->{$oid} ||
        $result->{$oid} eq 'noSuchInstance' ||
        $result->{$oid} eq 'noSuchObject' ||
        $result->{$oid} eq 'endOfMibView') {
      return undef;
    } else {
      $self->add_rawdata($oid, $result->{$oid});
      return $result->{$oid};
    }
  } else {
    return undef;
  }
}

# make_symbolic
# mib is the name of a mib (must be in mibs_and_oids)
# result is a hash-key oid->value
# indices is a array ref of array refs. [[1],[2],...] or [[1,0],[1,1],[2,0]..
sub make_symbolic {
  my ($self, $mib, $result, $indices) = @_;
  $self->require_mib($mib);
  my @entries = ();
  if (! wantarray && ref(\$result) eq "SCALAR" && ref(\$indices) eq "SCALAR") {
    # $self->make_symbolic('CISCO-IETF-NAT-MIB', 'cnatProtocolStatsName', $self->{cnatProtocolStatsName});
    my $oid = $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$result};
    $result = { $oid => $self->{$result} };
    $indices = [[]];
  }
  foreach my $index (@{$indices}) {
    # skip [], [[]], [[undef]]
    if (ref($index) eq "ARRAY") {
      if (scalar(@{$index}) == 0) {
        next;
      } elsif (!defined $index->[0]) {
        next;
      }
    }
    my $mo = {};
    my $idx = join('.', @{$index}); # index can be multi-level
    foreach my $symoid
        (keys %{$Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}}) {
      my $oid = $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$symoid};
      if (ref($oid) ne 'HASH') {
        my $fulloid = $oid . '.'.$idx;
        if (exists $result->{$fulloid}) {
          if (exists $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$symoid.'Definition'}) {
            if (ref($Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$symoid.'Definition'}) eq 'HASH') {
              if (exists $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$symoid.'Definition'}->{$result->{$fulloid}}) {
                $mo->{$symoid} = $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$symoid.'Definition'}->{$result->{$fulloid}};
              } else {
                $mo->{$symoid} = 'unknown_'.$result->{$fulloid};
              }
            } elsif ($Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$symoid.'Definition'} =~ /^OID::(.*)/) {
              my $othermib = $1;
              my $value_which_is_a_oid = $result->{$fulloid};
              $value_which_is_a_oid =~ s/^\.//g;
              my @result = grep { $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$othermib}->{$_} eq $value_which_is_a_oid } keys %{$Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$othermib}};
              if (scalar(@result)) {
                $mo->{$symoid} = $result[0];
              } else {
                $mo->{$symoid} = 'unknown_'.$result->{$fulloid};
              }
            } elsif ($Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$symoid.'Definition'} =~ /^(.*?)::(.*)/) {
              my $mib = $1;
              my $definition = $2;
              if  (exists $Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{$mib} &&
                  exists $Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{$mib}->{$definition} &&
                  ref($Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{$mib}->{$definition}) eq 'CODE') {
                $mo->{$symoid} = $Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{$mib}->{$definition}->($result->{$fulloid});
              } elsif  (exists $Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{$mib} &&
                  exists $Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{$mib}->{$definition} &&
                  ref($Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{$mib}->{$definition}) eq 'HASH' &&
                  exists $Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{$mib}->{$definition}->{$result->{$fulloid}}) {
                $mo->{$symoid} = $Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{$mib}->{$definition}->{$result->{$fulloid}};
              } else {
                $mo->{$symoid} = 'unknown_'.$result->{$fulloid};
              }
            } else {
              $mo->{$symoid} = 'unknown_'.$result->{$fulloid};
              # oder $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$symoid.'Definition'}?
            }
          } else {
            $mo->{$symoid} = $result->{$fulloid};
          }
        }
      }
    }
    push(@entries, $mo);
  }
  if (@{$indices} and scalar(@{$indices}) == 1 and !defined $indices->[0]->[0]) {
    my $mo = {};
    foreach my $symoid
        (keys %{$Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}}) {
      my $oid = $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$symoid};
      if (ref($oid) ne 'HASH') {
        if (exists $result->{$oid}) {
          if (exists $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$symoid.'Definition'}) {
            if (ref($Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$symoid.'Definition'}) eq 'HASH') {
              if (exists $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$symoid.'Definition'}->{$result->{$oid}}) {
                $mo->{$symoid} = $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$symoid.'Definition'}->{$result->{$oid}};
                push(@entries, $mo);
              }
            } elsif ($Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$symoid.'Definition'} =~ /^(.*?)::(.*)/) {
              my $mib = $1;
              my $definition = $2;
              if  (exists $Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{$mib} &&
                  exists $Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{$mib}->{$definition} &&
                  ref($Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{$mib}->{$definition}) eq 'CODE') {
                $mo->{$symoid} = $Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{$mib}->{$definition}->($result->{$oid});
              } elsif  (exists $Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{$mib} &&
                  exists $Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{$mib}->{$definition} &&
                  ref($Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{$mib}->{$definition}) eq 'HASH' &&
                  exists $Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{$mib}->{$definition}->{$result->{$oid}}) {
                $mo->{$symoid} = $Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{$mib}->{$definition}->{$result->{$oid}};
              } else {
                $mo->{$symoid} = 'unknown_'.$result->{$oid};
              }
            } else {
              $mo->{$symoid} = 'unknown_'.$result->{$oid};
              # oder $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$symoid.'Definition'}?
            }
          }
        }
      }
    }
    push(@entries, $mo) if keys %{$mo};
  }
  if (wantarray) {
    return @entries;
  } else {
    foreach my $entry (@entries) {
      foreach my $key (keys %{$entry}) {
        $self->{$key} = $entry->{$key};
      }
    }
  }
}

sub sort_oids {
  my ($self, $oids) = @_;
  $oids ||= [];
  my @sortedkeys = map { $_->[0] }
      sort { $a->[1] cmp $b->[1] }
          map { [$_,
                  join '', map { sprintf("%30d",$_) } split( /\./, $_)
                ] } @{$oids};
  return @sortedkeys;
}

sub get_matching_oids {
  my ($self, %params) = @_;
  my $result = {};
  $self->debug(sprintf "get_matching_oids %s", Data::Dumper::Dumper(\%params));
  foreach my $oid (@{$params{'-columns'}}) {
    my $oidpattern = $oid;
    $oidpattern =~ s/\./\\./g;
    map { $result->{$_} = $Monitoring::GLPlugin::SNMP::rawdata->{$_} }
        grep /^$oidpattern(?=\.|$)/, keys %{$Monitoring::GLPlugin::SNMP::rawdata};
  }
  $self->debug(sprintf "get_matching_oids returns %d from %d oids", 
      scalar(keys %{$result}), scalar(keys %{$Monitoring::GLPlugin::SNMP::rawdata}));
  return $result;
}

sub get_indices {
  my ($self, %params) = @_;
  # -baseoid : entry
  # find all oids beginning with $entry
  # then skip one field for the sequence
  # then read the next numindices fields
  my $entrypat = $params{'-baseoid'};
  $entrypat =~ s/\./\\\./g;
  my @indices = map {
      /^$entrypat\.\d+\.(.*)/ && $1;
  } grep {
      /^$entrypat/
  } keys %{$Monitoring::GLPlugin::SNMP::rawdata};
  my %seen = ();
  my @o = map {[split /\./]} sort grep !$seen{$_}++, @indices;
  return @o;
}

# this flattens a n-dimensional array and returns the absolute position
# of the element at position idx1,idx2,...,idxn
# element 1,2 in table 0,0 0,1 0,2 1,0 1,1 1,2 2,0 2,1 2,2 is at pos 6
sub get_number {
  my ($self, $indexlists, @element) = @_;
  # $indexlists = zeiger auf array aus [1, 2]
  my $dimensions = scalar(@{$indexlists->[0]});
  my @sorted = ();
  my $number = 0;
  if ($dimensions == 1) {
    @sorted =
        sort { $a->[0] <=> $b->[0] } @{$indexlists};
  } elsif ($dimensions == 2) {
    @sorted =
        sort { $a->[0] <=> $b->[0] || $a->[1] <=> $b->[1] } @{$indexlists};
  } elsif ($dimensions == 3) {
    @sorted =
        sort { $a->[0] <=> $b->[0] ||
               $a->[1] <=> $b->[1] ||
               $a->[2] <=> $b->[2] } @{$indexlists};
  }
  foreach (@sorted) {
    if ($dimensions == 1) {
      if ($_->[0] == $element[0]) {
        last;
      }
    } elsif ($dimensions == 2) {
      if ($_->[0] == $element[0] && $_->[1] == $element[1]) {
        last;
      }
    } elsif ($dimensions == 3) {
      if ($_->[0] == $element[0] &&
          $_->[1] == $element[1] &&
          $_->[2] == $element[2]) {
        last;
      }
    }
    $number++;
  }
  return ++$number;
}

################################################################
# caching functions
# 
sub set_rawdata {
  my ($self, $rawdata) = @_;
  $Monitoring::GLPlugin::SNMP::rawdata = $rawdata;
}

sub add_rawdata {
  my ($self, $oid, $value) = @_;
  $Monitoring::GLPlugin::SNMP::rawdata->{$oid} = $value;
}

sub rawdata {
  my ($self) = @_;
  return $Monitoring::GLPlugin::SNMP::rawdata;
}

sub add_oidtrace {
  my ($self, $oid) = @_;
  $self->debug("cache: ".$oid);
  push(@{$Monitoring::GLPlugin::SNMP::oidtrace}, $oid);
}

#  $self->update_entry_cache(0, $mib, $table, $key_attr);
#  my @indices = $self->get_cache_indices();
sub get_cache_indices {
  my ($self, $mib, $table, $key_attr) = @_;
  if (ref($key_attr) ne "ARRAY") {
    $key_attr = [$key_attr];
  }
  my $cache = sprintf "%s_%s_%s_cache", 
      $mib, $table, join('#', @{$key_attr});
  my @indices = ();
  foreach my $key (keys %{$self->{$cache}}) {
    my ($descr, $index) = split('-//-', $key, 2);
    if ($self->opts->name) {
      if ($self->opts->regexp) {
        my $pattern = $self->opts->name;
        if ($descr =~ /$pattern/i) {
          push(@indices, $self->{$cache}->{$key});
        }
      } else {
        if ($self->opts->name =~ /^\d+$/) {
          if ($index == 1 * $self->opts->name) {
            push(@indices, [1 * $self->opts->name]);
          }
        } else {
          if (lc $descr eq lc $self->opts->name) {
            push(@indices, $self->{$cache}->{$key});
          }
        }
      }
    } else {
      push(@indices, $self->{$cache}->{$key});
    }
  }
  return @indices;
  return map { join('.', ref($_) eq "ARRAY" ? @{$_} : $_) } @indices;
}

sub get_entities {
  my ($self, $class, $filter) = @_;
  foreach ($self->get_sub_table('ENTITY-MIB', [
    'entPhysicalDescr',
    'entPhysicalName',
    'entPhysicalClass',
  ])) {
    my $new_object = $class->new(%{$_});
    next if (defined $filter && ! &$filter($new_object));
    push @{$self->{entities}}, $new_object;
  }
}

sub get_sub_table {
  my ($self, $mib, $names) = @_;
  $self->require_mib($mib);
  my @oids = map {
    $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{$mib}->{$_}
  } @$names;
  my $result = $self->get_entries(
    -columns => \@oids
  );
  my $indices = ();
  map { if ($_ =~ /\.(\d+)$/) { $indices->{$1} = [ $1 ]; } } keys %$result;
  my @indices = values %$indices;
  my @entries = $self->make_symbolic($mib, $result, \@indices);
  @entries = map { $_->{indices} = shift @indices; $_ } @entries;
  @entries = map { $_->{flat_indices} = join(".", @{$_->{indices}}); $_ } @entries;
  return @entries;
}

sub join_table {
  my ($self, $to, $from) = @_;
  my $to_i = {};
  foreach (@$to) {
    my $i = $_->{flat_indices};
    $to_i->{$i} = $_;
  }
  foreach my $f (@$from) {
    my $i = $f->{flat_indices};
    if (exists $to_i->{$i}) {
      foreach (keys %$f) {
        next if $_ =~ /indices/;
        $to_i->{$i}->{$_} = $f->{$_};
      }
    }
  }
}




package Monitoring::GLPlugin::SNMP::CSF;
#our @ISA = qw(Monitoring::GLPlugin::SNMP);
use Digest::MD5 qw(md5_hex);
use strict;

sub create_statefile {
  my ($self, %params) = @_;
  my $extension = "";
  $extension .= $params{name} ? '_'.$params{name} : '';
  if ($self->opts->community) {
    $extension .= md5_hex($self->opts->community);
  }
  $extension =~ s/\//_/g;
  $extension =~ s/\(/_/g;
  $extension =~ s/\)/_/g;
  $extension =~ s/\*/_/g;
  $extension =~ s/\s/_/g;
  if ($self->opts->snmpwalk && ! $self->opts->hostname) {
    return sprintf "%s/%s_%s%s", $self->statefilesdir(),
        'snmpwalk.file'.md5_hex($self->opts->snmpwalk),
        $self->clean_path($self->mode), $self->clean_path(lc $extension);
  } elsif ($self->opts->snmpwalk && $self->opts->hostname eq "walkhost") {
    return sprintf "%s/%s_%s%s", $self->statefilesdir(),
        'snmpwalk.file'.md5_hex($self->opts->snmpwalk),
        $self->clean_path($self->mode), $self->clean_path(lc $extension);
  } else {
    return sprintf "%s/%s_%s%s", $self->statefilesdir(),
        $self->opts->hostname,
        $self->clean_path($self->mode), $self->clean_path(lc $extension);
  }
}



package Monitoring::GLPlugin::SNMP::Item;
our @ISA = qw(Monitoring::GLPlugin::SNMP::CSF Monitoring::GLPlugin::Item Monitoring::GLPlugin::SNMP);
use strict;



package Monitoring::GLPlugin::SNMP::TableItem;
our @ISA = qw(Monitoring::GLPlugin::SNMP::CSF Monitoring::GLPlugin::TableItem Monitoring::GLPlugin::SNMP);
use strict;

sub ensure_index {
  my ($self, $key) = @_;
  $self->{$key} ||= $self->{flat_indices};
}

sub unhex_ip {
  my ($self, $value) = @_;
  if ($value && $value =~ /^0x(\w{8})/) {
    $value = join(".", unpack "C*", pack "H*", $1);
  } elsif ($value && $value =~ /^0x(\w{2} \w{2} \w{2} \w{2})/) {
    $value = $1;
    $value =~ s/ //g;
    $value = join(".", unpack "C*", pack "H*", $value);
  } elsif ($value && $value =~ /^([A-Z0-9]{2} [A-Z0-9]{2} [A-Z0-9]{2} [A-Z0-9]{2})/i) {
    $value = $1;
    $value =~ s/ //g;
    $value = join(".", unpack "C*", pack "H*", $value);
  } elsif ($value && unpack("H8", $value) =~ /(\w{2})(\w{2})(\w{2})(\w{2})/) {
    $value = join(".", map { hex($_) } ($1, $2, $3, $4));
  }
  return $value;
}

sub unhex_mac {
  my ($self, $value) = @_;
  if ($value && $value =~ /^0x(\w{12})/) {
    $value = join(".", unpack "C*", pack "H*", $1);
  } elsif ($value && $value =~ /^0x(\w{2}\s*\w{2}\s*\w{2}\s*\w{2}\s*\w{2}\s*\w{2})/) {
    $value = $1;
    $value =~ s/ //g;
    $value = join(":", unpack "C*", pack "H*", $value);
  } elsif ($value && unpack("H12", $value) =~ /(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})/) {
    $value = join(":", map { hex($_) } ($1, $2, $3, $4, $5, $6));
  }
  return $value;
}

sub unhex_octet_string {
  my ($self, $value) = @_;
  my $original = $value;
  $value =~ s/ //g;
  if ($value && $value =~ /^0x([0-9a-zA-Z]+)$/) {
    $value = join("", unpack "A*", pack "H*", $1);
  } elsif ($value && $value =~ /^([0-9a-zA-Z]+)$/) {
    $value = join("", unpack "A*", pack "H*", $1);
  } else {
    $value = $original;
  }
  return $value;
}



package Monitoring::GLPlugin::SNMP::MibsAndOids;
our @ISA = qw(Monitoring::GLPlugin::SNMP);

{
  no warnings qw(once);
  $Monitoring::GLPlugin::SNMP::MibsAndOids::discover_ids = {};
  $Monitoring::GLPlugin::SNMP::MibsAndOids::mib_ids = {};
  $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids = {};
  $Monitoring::GLPlugin::SNMP::MibsAndOids::definitions = {};
  $Monitoring::GLPlugin::SNMP::MibsAndOids::origin = {};
}



package Monitoring::GLPlugin::SNMP::MibsAndOids::MIB2MIB;

$Monitoring::GLPlugin::SNMP::MibsAndOids::origin->{'MIB-2-MIB'} = {
  url => "",
  name => "MIB-2-MIB",
};

$Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{'MIB-2-MIB'} = {
  sysDescr => '1.3.6.1.2.1.1.1',
  sysObjectID => '1.3.6.1.2.1.1.2',
  sysUpTime => '1.3.6.1.2.1.1.3',
  sysName => '1.3.6.1.2.1.1.5',
  sysORTable => '1.3.6.1.2.1.1.9',
  sysOREntry => '1.3.6.1.2.1.1.9.1',
  sysORIndex => '1.3.6.1.2.1.1.9.1.1',
  sysORID => '1.3.6.1.2.1.1.9.1.2',
  sysORDescr => '1.3.6.1.2.1.1.9.1.3',
  sysORUpTime => '1.3.6.1.2.1.1.9.1.4',
};



package Monitoring::GLPlugin::SNMP::MibsAndOids::SNMPFRAMEWORKMIB;

$Monitoring::GLPlugin::SNMP::MibsAndOids::origin->{'SNMP-FRAMEWORK-MIB'} = {
  url => "",
  name => "MIB-II",
};

$Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{'SNMP-FRAMEWORK-MIB'} = {
  snmpEngineID => '1.3.6.1.6.3.10.2.1.1.0',
  snmpEngineBoots => '1.3.6.1.6.3.10.2.1.2.0',
  snmpEngineTime => '1.3.6.1.6.3.10.2.1.3.0',
  snmpEngineMaxMessageSize => '1.3.6.1.6.3.10.2.1.4.0',
};



package Monitoring::GLPlugin::SNMP::MibsAndOids::BDTMIB;

$Monitoring::GLPlugin::SNMP::MibsAndOids::origin->{'BDT-MIB'} = {
  url => '',
  name => 'BDT-MIB',
};

$Monitoring::GLPlugin::SNMP::MibsAndOids::mib_ids->{'BDT-MIB'} = 
  '1.3.6.1.4.1.20884.10893.2.101.1';

$Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{'BDT-MIB'} = {
  'bdt' => '1.3.6.1.4.1.20884',
  'storage' => '1.3.6.1.4.1.20884.10893',
  'hardware' => '1.3.6.1.4.1.20884.10893.2',
  'bDTagent' => '1.3.6.1.4.1.20884.10893.2.101',
  'bDTAgentInfo' => '1.3.6.1.4.1.20884.10893.2.101.1',
  'bDTDisplayName' => '1.3.6.1.4.1.20884.10893.2.101.1.1',
  'bDTDescription' => '1.3.6.1.4.1.20884.10893.2.101.1.2',
  'bDTAgentVendor' => '1.3.6.1.4.1.20884.10893.2.101.1.3',
  'bDTAgentVersion' => '1.3.6.1.4.1.20884.10893.2.101.1.4',
  'bDTGlobalData' => '1.3.6.1.4.1.20884.10893.2.101.2',
  'bDTGlobalStatus' => '1.3.6.1.4.1.20884.10893.2.101.2.1',
  'bDTGlobalStatusDefinition' => 'BDT-MIB::bDTGlobalStatus',
  'bDTLastGlobalStatus' => '1.3.6.1.4.1.20884.10893.2.101.2.2',
  'bDTLastGlobalStatusDefinition' => 'BDT-MIB::bDTLastGlobalStatus',
  'bDTTimeStamp' => '1.3.6.1.4.1.20884.10893.2.101.2.3',
  'bDTGetTimeOut' => '1.3.6.1.4.1.20884.10893.2.101.2.4',
  'bDTErrorCode' => '1.3.6.1.4.1.20884.10893.2.101.2.5',
  'bDTRefreshRate' => '1.3.6.1.4.1.20884.10893.2.101.2.6',
  'bDTErrorData' => '1.3.6.1.4.1.20884.10893.2.101.2.9',
  'bDTDeviceInfo' => '1.3.6.1.4.1.20884.10893.2.101.4',
  'bDTDevSerialNumber' => '1.3.6.1.4.1.20884.10893.2.101.4.1',
  'bDTDevVendorID' => '1.3.6.1.4.1.20884.10893.2.101.4.2',
  'bDTDevProductID' => '1.3.6.1.4.1.20884.10893.2.101.4.3',
  'bDTDevFirmwareRev' => '1.3.6.1.4.1.20884.10893.2.101.4.4',
  'bDTDevRobFirmwareRev' => '1.3.6.1.4.1.20884.10893.2.101.4.5',
  'bDTDevBootcodeRev' => '1.3.6.1.4.1.20884.10893.2.101.4.6',
};

$Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{'BDT-MIB'} = {
  bDTGlobalStatus => {
    '1' => 'other',
    '2' => 'unknown',
    '3' => 'ok',
    '4' => 'non-critical',
    '5' => 'critical',
    '6' => 'non-Recoverable',
  },
  bDTLastGlobalStatus => {
    '1' => 'other',
    '2' => 'unknown',
    '3' => 'ok',
    '4' => 'non-critical',
    '5' => 'critical',
    '6' => 'non-recoverable',
  },
};



package Monitoring::GLPlugin::SNMP::MibsAndOids::ADICINTELLIGENTSTORAGEMIB;

$Monitoring::GLPlugin::SNMP::MibsAndOids::origin->{'ADIC-INTELLIGENT-STORAGE-MIB'} = {
  url => '',
  name => 'ADIC-INTELLIGENT-STORAGE-MIB',
};

$Monitoring::GLPlugin::SNMP::MibsAndOids::mib_ids->{'ADIC-INTELLIGENT-STORAGE-MIB'} = 
  '1.3.6.1.4.1.3764.1.1';

$Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{'ADIC-INTELLIGENT-STORAGE-MIB'} = {
  'productMibVersion' => '1.3.6.1.4.1.3764.1.1.10.1',
};

$Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{'ADIC-INTELLIGENT-STORAGE-MIB::1.23'} = {
  'enterprises' => '1.3.6.1.4.1',
  'quantum' => '1.3.6.1.4.1.3764',
  'storage' => '1.3.6.1.4.1.3764.1',
  'intelligent' => '1.3.6.1.4.1.3764.1.1',
  'productAgentInfo' => '1.3.6.1.4.1.3764.1.1.10',
  'productMibVersion' => '1.3.6.1.4.1.3764.1.1.10.1',
  'productSnmpAgentVersion' => '1.3.6.1.4.1.3764.1.1.10.2',
  'productName' => '1.3.6.1.4.1.3764.1.1.10.3',
  'productDisplayName' => '1.3.6.1.4.1.3764.1.1.10.4',
  'productDescription' => '1.3.6.1.4.1.3764.1.1.10.5',
  'productVendor' => '1.3.6.1.4.1.3764.1.1.10.6',
  'productVersion' => '1.3.6.1.4.1.3764.1.1.10.7',
  'productDisplayVersion' => '1.3.6.1.4.1.3764.1.1.10.8',
  'productLibraryClass' => '1.3.6.1.4.1.3764.1.1.10.9',
  'productLibraryClassDefinition' => {
    '1' => 'basic',
    '2' => 'intelligent',
    '10' => 'virtual',
  },
  'productSerialNumber' => '1.3.6.1.4.1.3764.1.1.10.10',
  'globalData' => '1.3.6.1.4.1.3764.1.1.20',
  'agentGlobalStatus' => '1.3.6.1.4.1.3764.1.1.20.1',
  'agentGlobalStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicAgentStatus',
  'agentLastGlobalStatus' => '1.3.6.1.4.1.3764.1.1.20.2',
  'agentLastGlobalStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicAgentStatus',
  'agentTimeStamp' => '1.3.6.1.4.1.3764.1.1.20.3',
  'agentGetTimeOut' => '1.3.6.1.4.1.3764.1.1.20.4',
  'agentModifiers' => '1.3.6.1.4.1.3764.1.1.20.5',
  'agentRefreshRate' => '1.3.6.1.4.1.3764.1.1.20.6',
  'components' => '1.3.6.1.4.1.3764.1.1.30',
  'componentTable' => '1.3.6.1.4.1.3764.1.1.30.10',
  'componentEntry' => '1.3.6.1.4.1.3764.1.1.30.10.1',
  'componentId' => '1.3.6.1.4.1.3764.1.1.30.10.1.1',
  'componentType' => '1.3.6.1.4.1.3764.1.1.30.10.1.2',
  'componentTypeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicComponentType',
  'componentDisplayName' => '1.3.6.1.4.1.3764.1.1.30.10.1.3',
  'componentInfo' => '1.3.6.1.4.1.3764.1.1.30.10.1.4',
  'componentLocation' => '1.3.6.1.4.1.3764.1.1.30.10.1.5',
  'componentVendor' => '1.3.6.1.4.1.3764.1.1.30.10.1.6',
  'componentSn' => '1.3.6.1.4.1.3764.1.1.30.10.1.7',
  'componentStatus' => '1.3.6.1.4.1.3764.1.1.30.10.1.8',
  'componentStatusDefinition' => {
    '1' => 'unknown',
    '2' => 'unused',
    '3' => 'ok',
    '4' => 'warning',
    '5' => 'unknown',
  },
  'componentControl' => '1.3.6.1.4.1.3764.1.1.30.10.1.9',
  'componentControlDefinition' => {
    '1' => 'resetColdStart',
    '2' => 'resetWarmStart',
    '3' => 'offline',
    '4' => 'online',
  },
  'componentREDId' => '1.3.6.1.4.1.3764.1.1.30.10.1.10',
  'componentFirmwareVersion' => '1.3.6.1.4.1.3764.1.1.30.10.1.11',
  'componentGeoAddrAisle' => '1.3.6.1.4.1.3764.1.1.30.10.1.12',
  'componentGeoAddrFrame' => '1.3.6.1.4.1.3764.1.1.30.10.1.13',
  'componentGeoAddrRack' => '1.3.6.1.4.1.3764.1.1.30.10.1.14',
  'componentGeoAddrChassis' => '1.3.6.1.4.1.3764.1.1.30.10.1.15',
  'componentGeoAddrBlade' => '1.3.6.1.4.1.3764.1.1.30.10.1.16',
  'componentIpAddress' => '1.3.6.1.4.1.3764.1.1.30.10.1.17',
  'software' => '1.3.6.1.4.1.3764.1.1.100',
  'hardware' => '1.3.6.1.4.1.3764.1.1.200',
  'powerAndCooling' => '1.3.6.1.4.1.3764.1.1.200.200',
  'powerSupplyTable' => '1.3.6.1.4.1.3764.1.1.200.200.10',
  'powerSupplyEntry' => '1.3.6.1.4.1.3764.1.1.200.200.10.1',
  'powerSupplyIndex' => '1.3.6.1.4.1.3764.1.1.200.200.10.1.1',
  'powerSupplyName' => '1.3.6.1.4.1.3764.1.1.200.200.10.1.2',
  'powerSupplyWattage' => '1.3.6.1.4.1.3764.1.1.200.200.10.1.3',
  'powerSupplyType' => '1.3.6.1.4.1.3764.1.1.200.200.10.1.4',
  'powerSupplyTypeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicVoltageType',
  'powerSupplyREDId' => '1.3.6.1.4.1.3764.1.1.200.200.10.1.5',
  'powerSupplyRatedVoltage' => '1.3.6.1.4.1.3764.1.1.200.200.10.1.6',
  'powerSupplyLocation' => '1.3.6.1.4.1.3764.1.1.200.200.10.1.7',
  'powerSupplyStatus' => '1.3.6.1.4.1.3764.1.1.200.200.10.1.8',
  'powerSupplyStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicPowerSupplyStatus',
  'voltageSensorTable' => '1.3.6.1.4.1.3764.1.1.200.200.20',
  'voltageSensorEntry' => '1.3.6.1.4.1.3764.1.1.200.200.20.1',
  'voltageSensorIndex' => '1.3.6.1.4.1.3764.1.1.200.200.20.1.1',
  'voltageSensorName' => '1.3.6.1.4.1.3764.1.1.200.200.20.1.2',
  'voltageSensorStatus' => '1.3.6.1.4.1.3764.1.1.200.200.20.1.3',
  'voltageSensorStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicSensorStatus',
  'voltageSensorType' => '1.3.6.1.4.1.3764.1.1.200.200.20.1.5',
  'voltageSensorTypeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicVoltageType',
  'voltageSensorNominalLo' => '1.3.6.1.4.1.3764.1.1.200.200.20.1.6',
  'voltageSensorNominalHi' => '1.3.6.1.4.1.3764.1.1.200.200.20.1.7',
  'voltageSensorWarningLo' => '1.3.6.1.4.1.3764.1.1.200.200.20.1.8',
  'voltageSensorWarningHi' => '1.3.6.1.4.1.3764.1.1.200.200.20.1.9',
  'voltageSensorLocation' => '1.3.6.1.4.1.3764.1.1.200.200.20.1.10',
  'voltageSensorREDId' => '1.3.6.1.4.1.3764.1.1.200.200.20.1.11',
  'temperatureSensorTable' => '1.3.6.1.4.1.3764.1.1.200.200.30',
  'temperatureSensorEntry' => '1.3.6.1.4.1.3764.1.1.200.200.30.1',
  'temperatureSensorIndex' => '1.3.6.1.4.1.3764.1.1.200.200.30.1.1',
  'temperatureSensorName' => '1.3.6.1.4.1.3764.1.1.200.200.30.1.2',
  'temperatureSensorStatus' => '1.3.6.1.4.1.3764.1.1.200.200.30.1.3',
  'temperatureSensorStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicSensorStatus',
  'temperatureSensorDegreesCelsius' => '1.3.6.1.4.1.3764.1.1.200.200.30.1.4',
  'temperatureSensorNominalLo' => '1.3.6.1.4.1.3764.1.1.200.200.30.1.5',
  'temperatureSensorNominalHi' => '1.3.6.1.4.1.3764.1.1.200.200.30.1.6',
  'temperatureSensorWarningLo' => '1.3.6.1.4.1.3764.1.1.200.200.30.1.7',
  'temperatureSensorWarningHi' => '1.3.6.1.4.1.3764.1.1.200.200.30.1.8',
  'temperatureSensorLocation' => '1.3.6.1.4.1.3764.1.1.200.200.30.1.9',
  'temperatureSensorREDId' => '1.3.6.1.4.1.3764.1.1.200.200.30.1.10',
  'coolingFanTable' => '1.3.6.1.4.1.3764.1.1.200.200.40',
  'coolingFanEntry' => '1.3.6.1.4.1.3764.1.1.200.200.40.1',
  'coolingFanIndex' => '1.3.6.1.4.1.3764.1.1.200.200.40.1.1',
  'coolingFanName' => '1.3.6.1.4.1.3764.1.1.200.200.40.1.2',
  'coolingFanStatus' => '1.3.6.1.4.1.3764.1.1.200.200.40.1.3',
  'coolingFanStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicSensorStatus',
  'coolingFanRPM' => '1.3.6.1.4.1.3764.1.1.200.200.40.1.4',
  'coolingFanNominalLo' => '1.3.6.1.4.1.3764.1.1.200.200.40.1.5',
  'coolingFanNominalHi' => '1.3.6.1.4.1.3764.1.1.200.200.40.1.6',
  'coolingFanWarningLo' => '1.3.6.1.4.1.3764.1.1.200.200.40.1.7',
  'coolingFanWarningHi' => '1.3.6.1.4.1.3764.1.1.200.200.40.1.8',
  'coolingFanLocation' => '1.3.6.1.4.1.3764.1.1.200.200.40.1.9',
  'coolingFanREDId' => '1.3.6.1.4.1.3764.1.1.200.200.40.1.10',
  'sml' => '1.3.6.1.4.1.3764.1.1.300',
  'network' => '1.3.6.1.4.1.3764.1.1.400',
  'notification' => '1.3.6.1.4.1.3764.1.1.500',
  'trapPayloadTable' => '1.3.6.1.4.1.3764.1.1.500.10',
  'trapPayloadEntry' => '1.3.6.1.4.1.3764.1.1.500.10.1',
  'trapSequenceNumber' => '1.3.6.1.4.1.3764.1.1.500.10.1.1',
  'trapSeverity' => '1.3.6.1.4.1.3764.1.1.500.10.1.2',
  'trapSeverityDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicTrapSeverity',
  'trapSummaryText' => '1.3.6.1.4.1.3764.1.1.500.10.1.3',
  'trapIntendedUsage' => '1.3.6.1.4.1.3764.1.1.500.10.1.4',
  'trapIntendedUsageDefinition' => {
    '1' => 'public',
    '2' => 'triggerRefresh',
  },
  'trapInstance' => '1.3.6.1.4.1.3764.1.1.500.10.1.5',
  'trapInstanceValue' => '1.3.6.1.4.1.3764.1.1.500.10.1.6',
};

$Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{'ADIC-INTELLIGENT-STORAGE-MIB::1.23'} = {
  'AdicDoorStatus' => {
    '1' => 'open',
    '2' => 'closed',
    '3' => 'closedAndLocked',
    '4' => 'closedAndUnlocked',
    '5' => 'controllerFailed',
    '6' => 'notInstalled',
    '7' => 'noData',
  },
  'AdicSensorStatus' => {
    '1' => 'nominal',
    '2' => 'warningLow',
    '3' => 'warningHigh',
    '4' => 'alarmLow',
    '5' => 'alarmHigh',
    '6' => 'notInstalled',
    '7' => 'noData',
  },
  'Boolean' => {
    '1' => 'true',
    '2' => 'false',
  },
  'AdicEnable' => {
    '1' => 'enabled',
    '2' => 'disabled',
  },
  'AdicPowerSupplyStatus' => {
    '1' => 'unknown',
    '2' => 'notInstalled',
    '3' => 'ok',
    '4' => 'poweredOff',
    '5' => 'failed',
  },
  'RowStatus' => {
    '1' => 'active',
    '2' => 'notInService',
    '3' => 'notReady',
    '4' => 'createAndGo',
    '5' => 'createAndWait',
    '6' => 'destroy',
  },
  'AdicTrapSeverity' => {
    '1' => 'emergency',
    '2' => 'alarm',
    '3' => 'warning',
    '4' => 'notice',
    '5' => 'informational',
  },
  'AdicInterfaceType' => {
    '1' => 'parallelSCSI',
    '2' => 'fibreChannel',
    '3' => 'mixedScsiAndFc',
  },
  'AdicVaryStatus' => {
    '1' => 'variedOn',
    '2' => 'variedOff',
    '3' => 'inTransition',
  },
  'AdicDriveStatus' => {
    '1' => 'idle',
    '2' => 'loading',
    '3' => 'ejecting',
    '4' => 'inserted',
    '5' => 'removed',
    '6' => 'notInstalled',
    '7' => 'noData',
  },
  'AdicOnlineStatus' => {
    '1' => 'online',
    '2' => 'offline',
    '3' => 'shutdown',
  },
  'AdicAgentStatus' => {
    '1' => 'other',
    '2' => 'unknown',
    '3' => 'ok',
    '4' => 'non-critical',
    '5' => 'critical',
    '6' => 'non-recoverable',
  },
  'AdicComponentType' => {
    '1' => 'mcb',
    '2' => 'cmb',
    '3' => 'fcIoBlade',
    '4' => 'scsiIoBlade',
    '5' => 'rcu',
    '6' => 'networkChassis',
    '7' => 'libaryModule',
    '8' => 'powerSupply',
    '9' => 'eeb',
    '10' => 'hdc',
  },
  'AdicVoltageType' => {
    '1' => 'dc',
    '2' => 'ac',
  },
  'AdicDateAndTime' => sub {
    my $value = shift;
    use Time::Local;
    if ($value && ($value =~ /^0x((\w{2} ){8,})/ || $value =~ /^((\w{2} ){8,})/)) {
      $value = $1;
      $value =~ s/ //g;
      my $year = hex substr($value, 0, 4);
      $value = substr($value, 4);
      my ($month, $day, $hour, $minute, $second,
          $dseconds, $dirutc, $hoursutc, $minutesutc) = unpack "C*", pack "H*", $value;
      return timegm($second, $minute, $hour, $day, $month-1, $year-1900);
    } elsif ($value && unpack("H22", $value) =~ /(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})/) {
      my $year = hex $1.$2;
      my ($month, $day, $hour, $minute, $second,
          $dseconds, $dirutc, $hoursutc, $minutesutc) =
          map { hex($_) } ($3, $4, $5, $6, $7, $8, $9, $10, $11);
      return timegm($second, $minute, $hour, $day, $month-1, $year-1900);
    }
    return $value;
  },
  'MIBVERSION' => '1.23',
  'AdicTowerStatus' => {
    '1' => 'open',
    '2' => 'closed',
    '3' => 'closedAndVariedOn',
    '4' => 'closedAndVariedOff',
    '5' => 'controllerFailed',
    '6' => 'notInstalled',
    '7' => 'noData',
  },
};

$Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{'ADIC-INTELLIGENT-STORAGE-MIB::1.33'} = {
  'enterprises' => '1.3.6.1.4.1',
  'adic' => '1.3.6.1.4.1.3764',
  'storage' => '1.3.6.1.4.1.3764.1',
  'intelligent' => '1.3.6.1.4.1.3764.1.1',
  'productAgentInfo' => '1.3.6.1.4.1.3764.1.1.10',
  'productMibVersion' => '1.3.6.1.4.1.3764.1.1.10.1',
  'productSnmpAgentVersion' => '1.3.6.1.4.1.3764.1.1.10.2',
  'productName' => '1.3.6.1.4.1.3764.1.1.10.3',
  'productDisplayName' => '1.3.6.1.4.1.3764.1.1.10.4',
  'productDescription' => '1.3.6.1.4.1.3764.1.1.10.5',
  'productVendor' => '1.3.6.1.4.1.3764.1.1.10.6',
  'productVersion' => '1.3.6.1.4.1.3764.1.1.10.7',
  'productDisplayVersion' => '1.3.6.1.4.1.3764.1.1.10.8',
  'productLibraryClass' => '1.3.6.1.4.1.3764.1.1.10.9',
  'productLibraryClassDefinition' => {
    '1' => 'basic',
    '2' => 'intelligent',
    '10' => 'virtual',
  },
  'productSerialNumber' => '1.3.6.1.4.1.3764.1.1.10.10',
  'globalData' => '1.3.6.1.4.1.3764.1.1.20',
  'agentGlobalStatus' => '1.3.6.1.4.1.3764.1.1.20.1',
  'agentGlobalStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicAgentStatus',
  'agentLastGlobalStatus' => '1.3.6.1.4.1.3764.1.1.20.2',
  'agentLastGlobalStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicAgentStatus',
  'agentTimeStamp' => '1.3.6.1.4.1.3764.1.1.20.3',
  'agentGetTimeOut' => '1.3.6.1.4.1.3764.1.1.20.4',
  'agentModifiers' => '1.3.6.1.4.1.3764.1.1.20.5',
  'agentRefreshRate' => '1.3.6.1.4.1.3764.1.1.20.6',
  'components' => '1.3.6.1.4.1.3764.1.1.30',
  'componentTable' => '1.3.6.1.4.1.3764.1.1.30.10',
  'componentEntry' => '1.3.6.1.4.1.3764.1.1.30.10.1',
  'componentId' => '1.3.6.1.4.1.3764.1.1.30.10.1.1',
  'componentType' => '1.3.6.1.4.1.3764.1.1.30.10.1.2',
  'componentTypeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicComponentType',
  'componentDisplayName' => '1.3.6.1.4.1.3764.1.1.30.10.1.3',
  'componentInfo' => '1.3.6.1.4.1.3764.1.1.30.10.1.4',
  'componentLocation' => '1.3.6.1.4.1.3764.1.1.30.10.1.5',
  'componentVendor' => '1.3.6.1.4.1.3764.1.1.30.10.1.6',
  'componentSn' => '1.3.6.1.4.1.3764.1.1.30.10.1.7',
  'componentStatus' => '1.3.6.1.4.1.3764.1.1.30.10.1.8',
  'componentStatusDefinition' => {
    '1' => 'unknown',
    '2' => 'unused',
    '3' => 'ok',
    '4' => 'warning',
    '5' => 'unknown',
  },
  'componentControl' => '1.3.6.1.4.1.3764.1.1.30.10.1.9',
  'componentControlDefinition' => {
    '1' => 'resetColdStart',
    '2' => 'resetWarmStart',
    '3' => 'offline',
    '4' => 'online',
  },
  'componentREDId' => '1.3.6.1.4.1.3764.1.1.30.10.1.10',
  'componentFirmwareVersion' => '1.3.6.1.4.1.3764.1.1.30.10.1.11',
  'componentGeoAddrAisle' => '1.3.6.1.4.1.3764.1.1.30.10.1.12',
  'componentGeoAddrFrame' => '1.3.6.1.4.1.3764.1.1.30.10.1.13',
  'componentGeoAddrRack' => '1.3.6.1.4.1.3764.1.1.30.10.1.14',
  'componentGeoAddrChassis' => '1.3.6.1.4.1.3764.1.1.30.10.1.15',
  'componentGeoAddrBlade' => '1.3.6.1.4.1.3764.1.1.30.10.1.16',
  'componentIpAddress' => '1.3.6.1.4.1.3764.1.1.30.10.1.17',
  'software' => '1.3.6.1.4.1.3764.1.1.100',
  'hardware' => '1.3.6.1.4.1.3764.1.1.200',
  'powerAndCooling' => '1.3.6.1.4.1.3764.1.1.200.200',
  'powerSupplyTable' => '1.3.6.1.4.1.3764.1.1.200.200.10',
  'powerSupplyEntry' => '1.3.6.1.4.1.3764.1.1.200.200.10.1',
  'powerSupplyIndex' => '1.3.6.1.4.1.3764.1.1.200.200.10.1.1',
  'powerSupplyName' => '1.3.6.1.4.1.3764.1.1.200.200.10.1.2',
  'powerSupplyWattage' => '1.3.6.1.4.1.3764.1.1.200.200.10.1.3',
  'powerSupplyType' => '1.3.6.1.4.1.3764.1.1.200.200.10.1.4',
  'powerSupplyTypeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicVoltageType',
  'powerSupplyREDId' => '1.3.6.1.4.1.3764.1.1.200.200.10.1.5',
  'powerSupplyRatedVoltage' => '1.3.6.1.4.1.3764.1.1.200.200.10.1.6',
  'powerSupplyLocation' => '1.3.6.1.4.1.3764.1.1.200.200.10.1.7',
  'voltageSensorTable' => '1.3.6.1.4.1.3764.1.1.200.200.20',
  'voltageSensorEntry' => '1.3.6.1.4.1.3764.1.1.200.200.20.1',
  'voltageSensorIndex' => '1.3.6.1.4.1.3764.1.1.200.200.20.1.1',
  'voltageSensorName' => '1.3.6.1.4.1.3764.1.1.200.200.20.1.2',
  'voltageSensorStatus' => '1.3.6.1.4.1.3764.1.1.200.200.20.1.3',
  'voltageSensorStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicSensorStatus',
  'voltageSensorType' => '1.3.6.1.4.1.3764.1.1.200.200.20.1.5',
  'voltageSensorTypeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicVoltageType',
  'voltageSensorNominalLo' => '1.3.6.1.4.1.3764.1.1.200.200.20.1.6',
  'voltageSensorNominalHi' => '1.3.6.1.4.1.3764.1.1.200.200.20.1.7',
  'voltageSensorWarningLo' => '1.3.6.1.4.1.3764.1.1.200.200.20.1.8',
  'voltageSensorWarningHi' => '1.3.6.1.4.1.3764.1.1.200.200.20.1.9',
  'voltageSensorLocation' => '1.3.6.1.4.1.3764.1.1.200.200.20.1.10',
  'voltageSensorREDId' => '1.3.6.1.4.1.3764.1.1.200.200.20.1.11',
  'temperatureSensorTable' => '1.3.6.1.4.1.3764.1.1.200.200.30',
  'temperatureSensorEntry' => '1.3.6.1.4.1.3764.1.1.200.200.30.1',
  'temperatureSensorIndex' => '1.3.6.1.4.1.3764.1.1.200.200.30.1.1',
  'temperatureSensorName' => '1.3.6.1.4.1.3764.1.1.200.200.30.1.2',
  'temperatureSensorStatus' => '1.3.6.1.4.1.3764.1.1.200.200.30.1.3',
  'temperatureSensorStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicSensorStatus',
  'temperatureSensorDegreesCelsius' => '1.3.6.1.4.1.3764.1.1.200.200.30.1.4',
  'temperatureSensorNominalLo' => '1.3.6.1.4.1.3764.1.1.200.200.30.1.5',
  'temperatureSensorNominalHi' => '1.3.6.1.4.1.3764.1.1.200.200.30.1.6',
  'temperatureSensorWarningLo' => '1.3.6.1.4.1.3764.1.1.200.200.30.1.7',
  'temperatureSensorWarningHi' => '1.3.6.1.4.1.3764.1.1.200.200.30.1.8',
  'temperatureSensorLocation' => '1.3.6.1.4.1.3764.1.1.200.200.30.1.9',
  'temperatureSensorREDId' => '1.3.6.1.4.1.3764.1.1.200.200.30.1.10',
  'coolingFanTable' => '1.3.6.1.4.1.3764.1.1.200.200.40',
  'coolingFanEntry' => '1.3.6.1.4.1.3764.1.1.200.200.40.1',
  'coolingFanIndex' => '1.3.6.1.4.1.3764.1.1.200.200.40.1.1',
  'coolingFanName' => '1.3.6.1.4.1.3764.1.1.200.200.40.1.2',
  'coolingFanStatus' => '1.3.6.1.4.1.3764.1.1.200.200.40.1.3',
  'coolingFanStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicSensorStatus',
  'coolingFanRPM' => '1.3.6.1.4.1.3764.1.1.200.200.40.1.4',
  'coolingFanNominalLo' => '1.3.6.1.4.1.3764.1.1.200.200.40.1.5',
  'coolingFanNominalHi' => '1.3.6.1.4.1.3764.1.1.200.200.40.1.6',
  'coolingFanWarningLo' => '1.3.6.1.4.1.3764.1.1.200.200.40.1.7',
  'coolingFanWarningHi' => '1.3.6.1.4.1.3764.1.1.200.200.40.1.8',
  'coolingFanLocation' => '1.3.6.1.4.1.3764.1.1.200.200.40.1.9',
  'coolingFanREDId' => '1.3.6.1.4.1.3764.1.1.200.200.40.1.10',
  'sml' => '1.3.6.1.4.1.3764.1.1.300',
  'network' => '1.3.6.1.4.1.3764.1.1.400',
  'notification' => '1.3.6.1.4.1.3764.1.1.500',
  'trapPayloadTable' => '1.3.6.1.4.1.3764.1.1.500.10',
  'trapPayloadEntry' => '1.3.6.1.4.1.3764.1.1.500.10.1',
  'trapSequenceNumber' => '1.3.6.1.4.1.3764.1.1.500.10.1.1',
  'trapSeverity' => '1.3.6.1.4.1.3764.1.1.500.10.1.2',
  'trapSummaryText' => '1.3.6.1.4.1.3764.1.1.500.10.1.3',
  'trapIntendedUsage' => '1.3.6.1.4.1.3764.1.1.500.10.1.4',
  'trapIntendedUsageDefinition' => {
    '1' => 'public',
    '2' => 'triggerRefresh',
  },
};

$Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{'ADIC-INTELLIGENT-STORAGE-MIB::1.33'} = {
  'AdicDriveStatus' => {
    '1' => 'idle',
    '2' => 'loading',
    '3' => 'ejecting',
    '4' => 'inserted',
    '5' => 'removed',
    '6' => 'notInstalled',
    '7' => 'noData',
  },
  'AdicInterfaceType' => {
    '1' => 'scsi',
    '2' => 'fibreChannel',
  },
  'MIBVERSION' => '1.33',
  'AdicVoltageType' => {
    '1' => 'dc',
    '2' => 'ac',
  },
  'AdicComponentType' => {
    '1' => 'mcb',
    '2' => 'cmb',
    '3' => 'ioBlade',
    '4' => 'rcu',
    '5' => 'networkChasis',
    '6' => 'controlModule',
    '7' => 'expansionModule',
    '8' => 'powerSupply',
  },
  'AdicTrapSeverity' => {
    '1' => 'emergency',
    '2' => 'alarm',
    '3' => 'warning',
    '4' => 'notice',
    '5' => 'informational',
  },
  'RowStatus' => {
    '1' => 'active',
    '2' => 'notInService',
    '3' => 'notReady',
    '4' => 'createAndGo',
    '5' => 'createAndWait',
    '6' => 'destroy',
  },
  'AdicAgentStatus' => {
    '1' => 'other',
    '2' => 'unknown',
    '3' => 'ok',
    '4' => 'non-critical',
    '5' => 'critical',
    '6' => 'non-recoverable',
  },
  'AdicOnlineStatus' => {
    '1' => 'online',
    '2' => 'offline',
    '3' => 'shutdown',
  },
  'AdicEnable' => {
    '1' => 'enabled',
    '2' => 'disabled',
  },
  'Boolean' => {
    '1' => 'true',
    '2' => 'false',
  },
  'AdicSensorStatus' => {
    '1' => 'nominal',
    '2' => 'warningLow',
    '3' => 'warningHigh',
    '4' => 'alarmLow',
    '5' => 'alarmHigh',
    '6' => 'notInstalled',
    '7' => 'noData',
  },
  'AdicDoorStatus' => {
    '1' => 'open',
    '2' => 'closed',
    '3' => 'closedAndLocked',
    '4' => 'closedAndUnlocked',
    '5' => 'contollerFailed',
    '6' => 'notInstalled',
    '7' => 'noData',
  },
};



package Monitoring::GLPlugin::SNMP::MibsAndOids::ADICMANAGEMENTMIB;

$Monitoring::GLPlugin::SNMP::MibsAndOids::origin->{'ADIC-MANAGEMENT-MIB'} = {
  url => '',
  name => 'ADIC-MANAGEMENT-MIB',
};

$Monitoring::GLPlugin::SNMP::MibsAndOids::mib_ids->{'ADIC-MANAGEMENT-MIB'} =
  '1.3.6.1.4.1.3764.1.1.200.20';

$Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{'ADIC-MANAGEMENT-MIB'} = {
};

$Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{'ADIC-MANAGEMENT-MIB'} = {
};

$Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{'ADIC-MANAGEMENT-MIB::1.45'} = {
  'enterprises' => '1.3.6.1.4.1',
  'hardware' => '1.3.6.1.4.1.3764.1.1.200',
  'management' => '1.3.6.1.4.1.3764.1.1.200.20',
  'globalStatus' => '1.3.6.1.4.1.3764.1.1.200.20.10',
  'globalStatusTable' => '1.3.6.1.4.1.3764.1.1.200.20.10.10',
  'globalStatusEntry' => '1.3.6.1.4.1.3764.1.1.200.20.10.10.1',
  'role' => '1.3.6.1.4.1.3764.1.1.200.20.10.10.1.1',
  'roleDefinition' => 'ADIC-MANAGEMENT-MIB::AdicControllerRole',
  'status' => '1.3.6.1.4.1.3764.1.1.200.20.10.10.1.2',
  'statusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicAgentStatus',
  'systemDateAndTime' => '1.3.6.1.4.1.3764.1.1.200.20.10.10.1.3',
  'systemDateAndTimeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicDateAndTime',
  'networkTimeServer1' => '1.3.6.1.4.1.3764.1.1.200.20.10.10.1.4',
  'networkTimeProtocol' => '1.3.6.1.4.1.3764.1.1.200.20.10.10.1.5',
  'networkTimeProtocolDefinition' => {
    '1' => 'ntp',
  },
  'networkTimeEnable' => '1.3.6.1.4.1.3764.1.1.200.20.10.10.1.6',
  'networkTimeEnableDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicEnable',
  'enableDaylightSavingsTime' => '1.3.6.1.4.1.3764.1.1.200.20.10.10.1.8',
  'enableDaylightSavingsTimeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicEnable',
  'networkTimeServer2' => '1.3.6.1.4.1.3764.1.1.200.20.10.10.1.9',
  'globalEthernetManager' => '1.3.6.1.4.1.3764.1.1.200.20.15',
  'globalEthernetTable' => '1.3.6.1.4.1.3764.1.1.200.20.15.10',
  'globalEthernetEntry' => '1.3.6.1.4.1.3764.1.1.200.20.15.10.1',
  'interfaceIndex' => '1.3.6.1.4.1.3764.1.1.200.20.15.10.1.1',
  'mcbHostName' => '1.3.6.1.4.1.3764.1.1.200.20.15.10.1.2',
  'ipAddress' => '1.3.6.1.4.1.3764.1.1.200.20.15.10.1.3',
  'dhcpStatus' => '1.3.6.1.4.1.3764.1.1.200.20.15.10.1.4',
  'dhcpStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicEnable',
  'ipAddressSubnetMask' => '1.3.6.1.4.1.3764.1.1.200.20.15.10.1.5',
  'speedAutoNegotiation' => '1.3.6.1.4.1.3764.1.1.200.20.15.10.1.6',
  'speedAutoNegotiationDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicEnable',
  'preferredSpeed' => '1.3.6.1.4.1.3764.1.1.200.20.15.10.1.7',
  'preferredSpeedDefinition' => 'ADIC-MANAGEMENT-MIB::AdicEthernetSpeed',
  'actualSpeed' => '1.3.6.1.4.1.3764.1.1.200.20.15.10.1.8',
  'actualSpeedDefinition' => 'ADIC-MANAGEMENT-MIB::AdicEthernetSpeed',
  'ethernetDuplex' => '1.3.6.1.4.1.3764.1.1.200.20.15.10.1.9',
  'ethernetDuplexDefinition' => {
    '1' => 'half',
    '2' => 'full',
  },
  'systemManager' => '1.3.6.1.4.1.3764.1.1.200.20.20',
  'systemManagerTable' => '1.3.6.1.4.1.3764.1.1.200.20.20.10',
  'systemManagerEntry' => '1.3.6.1.4.1.3764.1.1.200.20.20.10.1',
  'softwareComponentIndex' => '1.3.6.1.4.1.3764.1.1.200.20.20.10.1.1',
  'processRowStatus' => '1.3.6.1.4.1.3764.1.1.200.20.20.10.1.2',
  'processRowStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::RowStatus',
  'processPhysicalMemory' => '1.3.6.1.4.1.3764.1.1.200.20.20.10.1.3',
  'processResidentMemory' => '1.3.6.1.4.1.3764.1.1.200.20.20.10.1.4',
  'softwareInstallationTable' => '1.3.6.1.4.1.3764.1.1.200.20.20.20',
  'softwareInstallationEntry' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1',
  'installPackageName' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.1',
  'installProcessStatus' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.2',
  'installProcessStatusDefinition' => {
    '1' => 'ok',
    '2' => 'inProgress',
    '3' => 'failed',
    '4' => 'updateAborted',
  },
  'installCommand' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.3',
  'installCommandDefinition' => {
    '1' => 'download',
    '2' => 'install',
    '3' => 'abort',
    '4' => 'timeEstimate',
  },
  'installStatusText' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.4',
  'currentFirmwareVersion' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.5',
  'previousFirmwareVersion' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.6',
  'downloadedFirmwareVersion' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.7',
  'mcbInstallStatusText' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.9',
  'cmbInstallStatusText' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.10',
  'rcuInstallStatusText' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.11',
  'fcbInstallStatusText' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.12',
  'amcInstallStatusText' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.13',
  'mcbInstallProcessStatus' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.14',
  'mcbInstallProcessStatusDefinition' => 'ADIC-MANAGEMENT-MIB::AdicInstallStatus',
  'cmbInstallProcessStatus' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.15',
  'cmbInstallProcessStatusDefinition' => 'ADIC-MANAGEMENT-MIB::AdicInstallStatus',
  'rcuInstallProcessStatus' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.16',
  'rcuInstallProcessStatusDefinition' => 'ADIC-MANAGEMENT-MIB::AdicInstallStatus',
  'fcbInstallProcessStatus' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.17',
  'fcbInstallProcessStatusDefinition' => 'ADIC-MANAGEMENT-MIB::AdicInstallStatus',
  'amcInstallProcessStatus' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.18',
  'amcInstallProcessStatusDefinition' => 'ADIC-MANAGEMENT-MIB::AdicInstallStatus',
  'persistentData' => '1.3.6.1.4.1.3764.1.1.200.20.30',
  'persistentDataTable' => '1.3.6.1.4.1.3764.1.1.200.20.30.10',
  'persistentDataEntry' => '1.3.6.1.4.1.3764.1.1.200.20.30.10.1',
  'capacity' => '1.3.6.1.4.1.3764.1.1.200.20.30.10.1.1',
  'freeSpace' => '1.3.6.1.4.1.3764.1.1.200.20.30.10.1.2',
  'security' => '1.3.6.1.4.1.3764.1.1.200.20.40',
  'userTable' => '1.3.6.1.4.1.3764.1.1.200.20.40.20',
  'userEntry' => '1.3.6.1.4.1.3764.1.1.200.20.40.20.1',
  'userName' => '1.3.6.1.4.1.3764.1.1.200.20.40.20.1.1',
  'userRowStatus' => '1.3.6.1.4.1.3764.1.1.200.20.40.20.1.2',
  'userRowStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::RowStatus',
  'userGroup' => '1.3.6.1.4.1.3764.1.1.200.20.40.20.1.3',
  'userPassword' => '1.3.6.1.4.1.3764.1.1.200.20.40.20.1.4',
  'userLibAccessList' => '1.3.6.1.4.1.3764.1.1.200.20.40.20.1.5',
  'licensing' => '1.3.6.1.4.1.3764.1.1.200.20.50',
  'licenseKeyTable' => '1.3.6.1.4.1.3764.1.1.200.20.50.10',
  'licenseKeyEntry' => '1.3.6.1.4.1.3764.1.1.200.20.50.10.1',
  'licenseKeyIndex' => '1.3.6.1.4.1.3764.1.1.200.20.50.10.1.1',
  'licenseKeyRowStatus' => '1.3.6.1.4.1.3764.1.1.200.20.50.10.1.2',
  'licenseKeyRowStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::RowStatus',
  'key' => '1.3.6.1.4.1.3764.1.1.200.20.50.10.1.3',
  'licenseKeyDuration' => '1.3.6.1.4.1.3764.1.1.200.20.50.10.1.4',
  'licenseKeyDurationDefinition' => {
    '1' => 'permanent',
    '2' => 'transient',
  },
  'licenseKeyExpirationDate' => '1.3.6.1.4.1.3764.1.1.200.20.50.10.1.5',
  'licenseKeyExpirationDateDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicDateAndTime',
  'licenseKeyAppliedDate' => '1.3.6.1.4.1.3764.1.1.200.20.50.10.1.6',
  'licenseKeyAppliedDateDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicDateAndTime',
  'licenseFeatureTable' => '1.3.6.1.4.1.3764.1.1.200.20.50.20',
  'licenseFeatureEntry' => '1.3.6.1.4.1.3764.1.1.200.20.50.20.1',
  'licenseFeatureIndex' => '1.3.6.1.4.1.3764.1.1.200.20.50.20.1.1',
  'featureName' => '1.3.6.1.4.1.3764.1.1.200.20.50.20.1.2',
  'licenseFeatureQuantity' => '1.3.6.1.4.1.3764.1.1.200.20.50.20.1.3',
  'licensableFeatureTable' => '1.3.6.1.4.1.3764.1.1.200.20.50.30',
  'licensableFeatureEntry' => '1.3.6.1.4.1.3764.1.1.200.20.50.30.1',
  'licensableFeatureName' => '1.3.6.1.4.1.3764.1.1.200.20.50.30.1.1',
  'totalQuantityLicensed' => '1.3.6.1.4.1.3764.1.1.200.20.50.30.1.2',
  'eventManager' => '1.3.6.1.4.1.3764.1.1.200.20.70',
  'registrationTable' => '1.3.6.1.4.1.3764.1.1.200.20.70.10',
  'registrationEntry' => '1.3.6.1.4.1.3764.1.1.200.20.70.10.1',
  'hostIpAddress' => '1.3.6.1.4.1.3764.1.1.200.20.70.10.1.1',
  'udpPort' => '1.3.6.1.4.1.3764.1.1.200.20.70.10.1.2',
  'registrationRowStatus' => '1.3.6.1.4.1.3764.1.1.200.20.70.10.1.3',
  'registrationRowStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::RowStatus',
  'logTable' => '1.3.6.1.4.1.3764.1.1.200.20.70.20',
  'logEntry' => '1.3.6.1.4.1.3764.1.1.200.20.70.20.1',
  'logName' => '1.3.6.1.4.1.3764.1.1.200.20.70.20.1.1',
  'logSnapshotTable' => '1.3.6.1.4.1.3764.1.1.200.20.70.30',
  'logSnapshotEntry' => '1.3.6.1.4.1.3764.1.1.200.20.70.30.1',
  'logSnapshotCommand' => '1.3.6.1.4.1.3764.1.1.200.20.70.30.1.1',
  'logSnapshotCommandDefinition' => {
    '1' => 'retrieveLogs',
  },
  'physicalLibrary' => '1.3.6.1.4.1.3764.1.1.200.20.80',
  'phGeneralInfoTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.10',
  'phGeneralInfoEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1',
  'numElementDomains' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.1',
  'numPhSlots' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.2',
  'numPhIESlots' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.3',
  'numPhDrives' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.4',
  'onlineStatus' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.5',
  'onlineStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicOnlineStatus',
  'readiness' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.6',
  'readinessDefinition' => {
    '1' => 'ready',
    '2' => 'notReady',
  },
  'autoInventoryMode' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.7',
  'autoInventoryModeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicEnable',
  'autoCalibrateMode' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.8',
  'autoCalibrateModeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicEnable',
  'autoConfigureMode' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.9',
  'autoConfigureModeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicEnable',
  'numPhAisles' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.10',
  'operatingMode' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.11',
  'numStorageCartridges' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.12',
  'numCleaningCartridges' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.13',
  'physLibraryManagerLun' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.14',
  'physLibraryAutoCleaning' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.15',
  'physLibraryAutoCleaningDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicEnable',
  'physLibraryDoorStatus' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.16',
  'physLibraryDoorStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicDoorStatus',
  'numPhFrames' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.17',
  'totalRawCapacity' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.18',
  'totalFreeCapacity' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.19',
  'totalUsedCapacity' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.20',
  'logicalSNAdressingMode' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.21',
  'logicalSNAdressingModeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicEnable',
  'usedNumPhSlots' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.22',
  'numCODSlots' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.23',
  'usedNumCODSlots' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.24',
  'mediaDomainTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.20',
  'mediaDomainEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.20.1',
  'mediaDomainIndex' => '1.3.6.1.4.1.3764.1.1.200.20.80.20.1.1',
  'mediaDomainName' => '1.3.6.1.4.1.3764.1.1.200.20.80.20.1.2',
  'numStorageElements' => '1.3.6.1.4.1.3764.1.1.200.20.80.20.1.3',
  'numIeElements' => '1.3.6.1.4.1.3764.1.1.200.20.80.20.1.4',
  'numCleaningSlots' => '1.3.6.1.4.1.3764.1.1.200.20.80.20.1.5',
  'mediaTypeTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.30',
  'mediaTypeEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.30.1',
  'mediaTypeIndex' => '1.3.6.1.4.1.3764.1.1.200.20.80.30.1.1',
  'mediaTypeName' => '1.3.6.1.4.1.3764.1.1.200.20.80.30.1.2',
  'numDriveElements' => '1.3.6.1.4.1.3764.1.1.200.20.80.30.1.3',
  'phFrameTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.41',
  'phFrameEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.41.1',
  'phFrameType' => '1.3.6.1.4.1.3764.1.1.200.20.80.41.1.1',
  'phFrameTypeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicComponentType',
  'phFrameSerialNumber' => '1.3.6.1.4.1.3764.1.1.200.20.80.41.1.2',
  'phFrameNumRacks' => '1.3.6.1.4.1.3764.1.1.200.20.80.41.1.3',
  'phSegmentTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.55',
  'phSegmentEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.55.1',
  'phSegmentAisle' => '1.3.6.1.4.1.3764.1.1.200.20.80.55.1.1',
  'phSegmentFrame' => '1.3.6.1.4.1.3764.1.1.200.20.80.55.1.2',
  'phSegmentRack' => '1.3.6.1.4.1.3764.1.1.200.20.80.55.1.3',
  'phSegmentSection' => '1.3.6.1.4.1.3764.1.1.200.20.80.55.1.4',
  'phSegmentCol' => '1.3.6.1.4.1.3764.1.1.200.20.80.55.1.5',
  'phSegmentStartingRow' => '1.3.6.1.4.1.3764.1.1.200.20.80.55.1.6',
  'phSegmentSize' => '1.3.6.1.4.1.3764.1.1.200.20.80.55.1.7',
  'phSegmentType' => '1.3.6.1.4.1.3764.1.1.200.20.80.55.1.8',
  'phSegmentTypeDefinition' => 'ADIC-MANAGEMENT-MIB::AdicSegmentType',
  'phSegmentMediaDomain' => '1.3.6.1.4.1.3764.1.1.200.20.80.55.1.9',
  'phSegmentStatus' => '1.3.6.1.4.1.3764.1.1.200.20.80.55.1.10',
  'phSegmentStatusDefinition' => {
    '1' => 'installed',
    '2' => 'notInstalled',
    '3' => 'reservedForCleaning',
  },
  'phSegmentCodStatus' => '1.3.6.1.4.1.3764.1.1.200.20.80.55.1.11',
  'phSegmentCodStatusDefinition' => {
    '1' => 'enabled',
    '2' => 'disabled',
    '3' => 'noCod',
  },
  'phSegStartingAddress' => '1.3.6.1.4.1.3764.1.1.200.20.80.55.1.12',
  'phStorageSegTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.60',
  'phStorageSegEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.60.1',
  'phStorageSegSize' => '1.3.6.1.4.1.3764.1.1.200.20.80.60.1.1',
  'phTowerTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.65',
  'phTowerEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.65.1',
  'phTowerNumber' => '1.3.6.1.4.1.3764.1.1.200.20.80.65.1.1',
  'phTowerStatus' => '1.3.6.1.4.1.3764.1.1.200.20.80.65.1.2',
  'phTowerStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicTowerStatus',
  'phTowerREDId' => '1.3.6.1.4.1.3764.1.1.200.20.80.65.1.3',
  'phTowerREDIdDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicREDIdentifier',
  'phIeSegTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.70',
  'phIeSegEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.70.1',
  'phIeSegSize' => '1.3.6.1.4.1.3764.1.1.200.20.80.70.1.1',
  'phIeSegReserve' => '1.3.6.1.4.1.3764.1.1.200.20.80.70.1.2',
  'phIeSegReserveDefinition' => {
    '1' => 'reserve',
    '2' => 'release',
  },
  'phIeSegReservedBy' => '1.3.6.1.4.1.3764.1.1.200.20.80.70.1.3',
  'phIeSegOnlineStatus' => '1.3.6.1.4.1.3764.1.1.200.20.80.70.1.4',
  'phIeSegOnlineStatusDefinition' => {
    '1' => 'online',
    '2' => 'offline',
  },
  'phIeSegCommand' => '1.3.6.1.4.1.3764.1.1.200.20.80.70.1.5',
  'phIeSegCommandDefinition' => {
    '1' => 'import',
  },
  'phIeStationTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.75',
  'phIeStationEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.75.1',
  'phIeStationNumber' => '1.3.6.1.4.1.3764.1.1.200.20.80.75.1.1',
  'phIeStationDoorStatus' => '1.3.6.1.4.1.3764.1.1.200.20.80.75.1.2',
  'phIeStationDoorStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicDoorStatus',
  'phIeStationREDId' => '1.3.6.1.4.1.3764.1.1.200.20.80.75.1.3',
  'phIeStationREDIdDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicREDIdentifier',
  'phDriveSegTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.80',
  'phDriveSegEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.80.1',
  'phDriveSegSize' => '1.3.6.1.4.1.3764.1.1.200.20.80.80.1.1',
  'phDriveSegMediaType' => '1.3.6.1.4.1.3764.1.1.200.20.80.80.1.2',
  'phDriveSegInterfaceType' => '1.3.6.1.4.1.3764.1.1.200.20.80.80.1.3',
  'phDriveSegInterfaceTypeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicInterfaceType',
  'phCleaningSegTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.85',
  'phCleaningSegEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.85.1',
  'phCleaningSegSize' => '1.3.6.1.4.1.3764.1.1.200.20.80.85.1.1',
  'phCleaningSegRowStatus' => '1.3.6.1.4.1.3764.1.1.200.20.80.85.1.2',
  'phCleaningSegRowStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::RowStatus',
  'phStorageSlotTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.90',
  'phStorageSlotEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.90.1',
  'phStorageRow' => '1.3.6.1.4.1.3764.1.1.200.20.80.90.1.1',
  'phStorageElementAddr' => '1.3.6.1.4.1.3764.1.1.200.20.80.90.1.2',
  'phIeSlotTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.100',
  'phIeSlotEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.100.1',
  'phIeRow' => '1.3.6.1.4.1.3764.1.1.200.20.80.100.1.1',
  'phIeElementAddr' => '1.3.6.1.4.1.3764.1.1.200.20.80.100.1.2',
  'phIeMediaPresent' => '1.3.6.1.4.1.3764.1.1.200.20.80.100.1.3',
  'phIeMediaPresentDefinition' => {
    '1' => 'yes',
    '2' => 'no',
    '3' => 'error',
  },
  'phIeMediaId' => '1.3.6.1.4.1.3764.1.1.200.20.80.100.1.4',
  'phDriveTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.110',
  'phDriveEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1',
  'phDriveRow' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.1',
  'phDriveElementAddr' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.2',
  'phDriveScsiId' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.3',
  'phDriveScsiLun' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.4',
  'phDriveWwn' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.5',
  'phDriveVendor' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.6',
  'phDriveProduct' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.7',
  'phDriveSerialNumber' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.8',
  'phDriveNeedsCleaning' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.9',
  'phDriveNeedsCleaningDefinition' => {
    '1' => 'true',
    '2' => 'false',
    '3' => 'immediate',
  },
  'phDriveAutoCleaning' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.10',
  'phDriveAutoCleaningDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::Boolean',
  'phDriveInterfaceType' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.11',
  'phDriveInterfaceTypeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicInterfaceType',
  'phDriveFcLoopId' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.12',
  'phDriveFcLoopIdMode' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.13',
  'phDriveFcLoopIdModeDefinition' => {
    '1' => 'soft',
    '2' => 'hard',
  },
  'phDriveFcHardId' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.14',
  'phDriveStatus' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.15',
  'phDriveStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicDriveStatus',
  'phDriveCommand' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.16',
  'phDriveFcPortId' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.17',
  'phDriveCompressionOn' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.18',
  'phDriveCompressionOnDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::Boolean',
  'phDriveWriteProtected' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.19',
  'phDriveWriteProtectedDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::Boolean',
  'phDriveNumLoads' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.20',
  'phDriveNumCleans' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.21',
  'phDrivePowerStatus' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.22',
  'phDrivePowerStatusDefinition' => {
    '1' => 'poweredOn',
    '2' => 'poweredOff',
  },
  'phDriveReadErrors' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.23',
  'phDriveWriteErrors' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.24',
  'phDriveMbytesRead' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.25',
  'phDriveMbytesWritten' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.26',
  'phDriveFirmwareVersion' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.27',
  'phDriveREDId' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.28',
  'phDriveREDIdDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicREDIdentifier',
  'phDriveOnlineStatus' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.29',
  'phDriveOnlineStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicOnlineStatus',
  'phDriveErrorCodeBytes' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.30',
  'phDriveRasStatus' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.31',
  'phDriveRasStatusDefinition' => 'ADIC-MANAGEMENT-MIB::AdicStatusGroupState',
  'phDriveWwPortName' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.32',
  'phDriveIpAddress' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.33',
  'phDriveVaryStatus' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.34',
  'phDriveVaryStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicVaryStatus',
  'phDriveStatHistoryTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.112',
  'phDriveStatHistoryEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.112.1',
  'phHourIndex' => '1.3.6.1.4.1.3764.1.1.200.20.80.112.1.1',
  'phHourlyMBytesRead' => '1.3.6.1.4.1.3764.1.1.200.20.80.112.1.2',
  'phHourlyMBytesWritten' => '1.3.6.1.4.1.3764.1.1.200.20.80.112.1.3',
  'phHourlyMounts' => '1.3.6.1.4.1.3764.1.1.200.20.80.112.1.4',
  'phDrivePorts' => '1.3.6.1.4.1.3764.1.1.200.20.80.116',
  'fcDrivePortTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.116.10',
  'fcDrivePortEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.116.10.1',
  'fcPortPreferredSpeed' => '1.3.6.1.4.1.3764.1.1.200.20.80.116.10.1.1',
  'fcPortPreferredSpeedDefinition' => 'ADIC-MANAGEMENT-MIB::AdicFcPortSpeed',
  'fcPortNegotiatedSpeed' => '1.3.6.1.4.1.3764.1.1.200.20.80.116.10.1.2',
  'fcPortNegotiatedSpeedDefinition' => 'ADIC-MANAGEMENT-MIB::AdicFcPortSpeed',
  'fcPortPreferredType' => '1.3.6.1.4.1.3764.1.1.200.20.80.116.10.1.3',
  'fcPortPreferredTypeDefinition' => 'ADIC-MANAGEMENT-MIB::AdicFcPortType',
  'fcPortNegotiatedType' => '1.3.6.1.4.1.3764.1.1.200.20.80.116.10.1.4',
  'fcPortNegotiatedTypeDefinition' => 'ADIC-MANAGEMENT-MIB::AdicFcPortType',
  'fcPortTypeQualifier' => '1.3.6.1.4.1.3764.1.1.200.20.80.116.10.1.5',
  'fcPortTypeQualifierDefinition' => {
    '1' => 'public',
    '2' => 'private',
  },
  'phMediaTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.120',
  'phMediaEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.120.1',
  'phMediaBarCode' => '1.3.6.1.4.1.3764.1.1.200.20.80.120.1.1',
  'phMediaDomain' => '1.3.6.1.4.1.3764.1.1.200.20.80.120.1.2',
  'phMediaType' => '1.3.6.1.4.1.3764.1.1.200.20.80.120.1.3',
  'phMediaElementAddress' => '1.3.6.1.4.1.3764.1.1.200.20.80.120.1.4',
  'phMediaMounts' => '1.3.6.1.4.1.3764.1.1.200.20.80.120.1.5',
  'phMediaReadErrors' => '1.3.6.1.4.1.3764.1.1.200.20.80.120.1.6',
  'phMediaWriteErrors' => '1.3.6.1.4.1.3764.1.1.200.20.80.120.1.7',
  'phMediaCapacity' => '1.3.6.1.4.1.3764.1.1.200.20.80.120.1.8',
  'phMediaFreeSpace' => '1.3.6.1.4.1.3764.1.1.200.20.80.120.1.9',
  'phMediaExported' => '1.3.6.1.4.1.3764.1.1.200.20.80.120.1.10',
  'phMediaExportedDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::Boolean',
  'phMediaImportTimestamp' => '1.3.6.1.4.1.3764.1.1.200.20.80.120.1.11',
  'phMediaImportTimestampDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicDateAndTime',
  'phMediaExportTimestamp' => '1.3.6.1.4.1.3764.1.1.200.20.80.120.1.12',
  'phMediaExportTimestampDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicDateAndTime',
  'phTransportTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.130',
  'phTransportEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.130.1',
  'phTransportElementAddress' => '1.3.6.1.4.1.3764.1.1.200.20.80.130.1.1',
  'phTransportNumRecoveredGets' => '1.3.6.1.4.1.3764.1.1.200.20.80.130.1.2',
  'phTransportNumRecoveredPuts' => '1.3.6.1.4.1.3764.1.1.200.20.80.130.1.3',
  'phTransportNumRecoveredScans' => '1.3.6.1.4.1.3764.1.1.200.20.80.130.1.4',
  'phTransportNumPuts' => '1.3.6.1.4.1.3764.1.1.200.20.80.130.1.5',
  'phTransportREDId' => '1.3.6.1.4.1.3764.1.1.200.20.80.130.1.6',
  'phTransportREDIdDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicREDIdentifier',
  'phTransportDomainTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.132',
  'phTransportDomainEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.132.1',
  'phTransportDomainIndex' => '1.3.6.1.4.1.3764.1.1.200.20.80.132.1.1',
  'phCleaningMediaTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.140',
  'phCleaningMediaEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.140.1',
  'phCleaningMediaRow' => '1.3.6.1.4.1.3764.1.1.200.20.80.140.1.1',
  'phCleaningMediaStatus' => '1.3.6.1.4.1.3764.1.1.200.20.80.140.1.2',
  'phCleaningMediaStatusDefinition' => {
    '1' => 'allocated',
    '2' => 'unallocated',
  },
  'phCleaningMediaTypeIndex' => '1.3.6.1.4.1.3764.1.1.200.20.80.140.1.3',
  'phCleaningMediaVendorId' => '1.3.6.1.4.1.3764.1.1.200.20.80.140.1.4',
  'phCleaningMediaBarcode' => '1.3.6.1.4.1.3764.1.1.200.20.80.140.1.5',
  'phCleaningMediaUseCount' => '1.3.6.1.4.1.3764.1.1.200.20.80.140.1.6',
  'phCleaningMediaMaxUses' => '1.3.6.1.4.1.3764.1.1.200.20.80.140.1.7',
  'phCleaningMediaImportTimestamp' => '1.3.6.1.4.1.3764.1.1.200.20.80.140.1.8',
  'phCleaningMediaImportTimestampDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicDateAndTime',
  'logicalLibrary' => '1.3.6.1.4.1.3764.1.1.200.20.90',
  'loGeneralInfoTable' => '1.3.6.1.4.1.3764.1.1.200.20.90.10',
  'loGeneralInfoEntry' => '1.3.6.1.4.1.3764.1.1.200.20.90.10.1',
  'maxLogicalLibraries' => '1.3.6.1.4.1.3764.1.1.200.20.90.10.1.1',
  'numLogicalLibraries' => '1.3.6.1.4.1.3764.1.1.200.20.90.10.1.2',
  'masterOnlineStatus' => '1.3.6.1.4.1.3764.1.1.200.20.90.10.1.3',
  'masterOnlineStatusDefinition' => {
    '1' => 'online',
    '2' => 'offline',
  },
  'numVendorIds' => '1.3.6.1.4.1.3764.1.1.200.20.90.10.1.4',
  'autoPartitionTable' => '1.3.6.1.4.1.3764.1.1.200.20.90.12',
  'autoPartitionEntry' => '1.3.6.1.4.1.3764.1.1.200.20.90.12.1',
  'numAutoPartition' => '1.3.6.1.4.1.3764.1.1.200.20.90.12.1.1',
  'autoPartitionCommand' => '1.3.6.1.4.1.3764.1.1.200.20.90.12.1.2',
  'autoPartitionCommandDefinition' => {
    '1' => 'autoPartition',
  },
  'vendorIdTable' => '1.3.6.1.4.1.3764.1.1.200.20.90.15',
  'vendorIdEntry' => '1.3.6.1.4.1.3764.1.1.200.20.90.15.1',
  'vendorIdIndex' => '1.3.6.1.4.1.3764.1.1.200.20.90.15.1.1',
  'vendorName' => '1.3.6.1.4.1.3764.1.1.200.20.90.15.1.2',
  'numProductIds' => '1.3.6.1.4.1.3764.1.1.200.20.90.15.1.3',
  'productIdTable' => '1.3.6.1.4.1.3764.1.1.200.20.90.17',
  'productIdEntry' => '1.3.6.1.4.1.3764.1.1.200.20.90.17.1',
  'productIdIndex' => '1.3.6.1.4.1.3764.1.1.200.20.90.17.1.1',
  'productIdName' => '1.3.6.1.4.1.3764.1.1.200.20.90.17.1.2',
  'productDrivesMin' => '1.3.6.1.4.1.3764.1.1.200.20.90.17.1.3',
  'productDrivesMax' => '1.3.6.1.4.1.3764.1.1.200.20.90.17.1.4',
  'productSlotsMin' => '1.3.6.1.4.1.3764.1.1.200.20.90.17.1.5',
  'productSlotsMax' => '1.3.6.1.4.1.3764.1.1.200.20.90.17.1.6',
  'productIeMin' => '1.3.6.1.4.1.3764.1.1.200.20.90.17.1.7',
  'productIeMax' => '1.3.6.1.4.1.3764.1.1.200.20.90.17.1.8',
  'logicalLibraryTable' => '1.3.6.1.4.1.3764.1.1.200.20.90.20',
  'logicalLibraryEntry' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1',
  'logicalLibraryIndex' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.1',
  'command' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.2',
  'commandDefinition' => {
    '1' => 'createSimple',
    '2' => 'createExpert',
    '3' => 'modify',
    '4' => 'delete',
  },
  'name' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.3',
  'assignedLun' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.4',
  'vendorId' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.5',
  'productId' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.6',
  'mediaDomain' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.7',
  'mediaType' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.8',
  'numSlots' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.9',
  'numIE' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.10',
  'numDrives' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.11',
  'loStatus' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.12',
  'loStatusDefinition' => {
    '1' => 'online',
    '2' => 'offline',
  },
  'automaticCleaning' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.13',
  'automaticCleaningDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicEnable',
  'mediaTypeChecking' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.14',
  'mediaTypeCheckingDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicEnable',
  'serialNumber' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.15',
  'loInterfaceType' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.16',
  'loInterfaceTypeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicInterfaceType',
  'loNumLibraries' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.17',
  'loLtoTapeTags' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.18',
  'loLtoTapeTagsDefinition' => {
    '1' => 'prefix',
    '2' => 'suffix',
    '3' => 'disabled',
  },
  'ltfsLicensed' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.19',
  'ltfsLicensedDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicEnable',
  'loSegmentTable' => '1.3.6.1.4.1.3764.1.1.200.20.90.25',
  'loSegmentEntry' => '1.3.6.1.4.1.3764.1.1.200.20.90.25.1',
  'loSegmentAisle' => '1.3.6.1.4.1.3764.1.1.200.20.90.25.1.1',
  'loSegmentFrame' => '1.3.6.1.4.1.3764.1.1.200.20.90.25.1.2',
  'loSegmentRack' => '1.3.6.1.4.1.3764.1.1.200.20.90.25.1.3',
  'loSegmentSection' => '1.3.6.1.4.1.3764.1.1.200.20.90.25.1.4',
  'loSegmentCol' => '1.3.6.1.4.1.3764.1.1.200.20.90.25.1.5',
  'loSegmentStartingRow' => '1.3.6.1.4.1.3764.1.1.200.20.90.25.1.6',
  'loSegmentSize' => '1.3.6.1.4.1.3764.1.1.200.20.90.25.1.7',
  'loSegmentType' => '1.3.6.1.4.1.3764.1.1.200.20.90.25.1.8',
  'loSegmentTypeDefinition' => 'ADIC-MANAGEMENT-MIB::AdicSegmentType',
  'loSegmentMediaDomain' => '1.3.6.1.4.1.3764.1.1.200.20.90.25.1.9',
  'loSegmentBelongsTo' => '1.3.6.1.4.1.3764.1.1.200.20.90.25.1.10',
  'loSegmentCommand' => '1.3.6.1.4.1.3764.1.1.200.20.90.25.1.11',
  'loSegmentCommandDefinition' => {
    '1' => 'allocate',
    '2' => 'free',
    '3' => 'reserveForCleaning',
  },
  'loSegmentStatus' => '1.3.6.1.4.1.3764.1.1.200.20.90.25.1.12',
  'loSegmentStatusDefinition' => {
    '1' => 'allocated',
    '2' => 'unallocated',
  },
  'loSegmentStartingAddress' => '1.3.6.1.4.1.3764.1.1.200.20.90.25.1.13',
  'loSegmentBelongsToTable' => '1.3.6.1.4.1.3764.1.1.200.20.90.27',
  'loSegmentBelongsToEntry' => '1.3.6.1.4.1.3764.1.1.200.20.90.27.1',
  'loSegmentAssignedTo' => '1.3.6.1.4.1.3764.1.1.200.20.90.27.1.1',
  'loStorageSegTable' => '1.3.6.1.4.1.3764.1.1.200.20.90.30',
  'loStorageSegEntry' => '1.3.6.1.4.1.3764.1.1.200.20.90.30.1',
  'loStorageSegSize' => '1.3.6.1.4.1.3764.1.1.200.20.90.30.1.1',
  'loStorageSegStartingAddress' => '1.3.6.1.4.1.3764.1.1.200.20.90.30.1.2',
  'loIeSegTable' => '1.3.6.1.4.1.3764.1.1.200.20.90.40',
  'loIeSegEntry' => '1.3.6.1.4.1.3764.1.1.200.20.90.40.1',
  'loIeSegSize' => '1.3.6.1.4.1.3764.1.1.200.20.90.40.1.1',
  'loIeSegReserve' => '1.3.6.1.4.1.3764.1.1.200.20.90.40.1.2',
  'loIeSegReserveDefinition' => {
    '1' => 'reserve',
    '2' => 'release',
  },
  'loIeSegReservedBy' => '1.3.6.1.4.1.3764.1.1.200.20.90.40.1.3',
  'loIeSegStartingAddress' => '1.3.6.1.4.1.3764.1.1.200.20.90.40.1.4',
  'loDriveSegTable' => '1.3.6.1.4.1.3764.1.1.200.20.90.50',
  'loDriveSegEntry' => '1.3.6.1.4.1.3764.1.1.200.20.90.50.1',
  'loDriveSegSize' => '1.3.6.1.4.1.3764.1.1.200.20.90.50.1.1',
  'loDriveSegStartingAddress' => '1.3.6.1.4.1.3764.1.1.200.20.90.50.1.2',
  'loDriveSegMediaType' => '1.3.6.1.4.1.3764.1.1.200.20.90.50.1.3',
  'loDriveSegInterfaceType' => '1.3.6.1.4.1.3764.1.1.200.20.90.50.1.4',
  'loDriveSegInterfaceTypeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicInterfaceType',
  'loStorageSlotTable' => '1.3.6.1.4.1.3764.1.1.200.20.90.60',
  'loStorageSlotEntry' => '1.3.6.1.4.1.3764.1.1.200.20.90.60.1',
  'loStorageRow' => '1.3.6.1.4.1.3764.1.1.200.20.90.60.1.1',
  'loIeSlotTable' => '1.3.6.1.4.1.3764.1.1.200.20.90.70',
  'loIeSlotEntry' => '1.3.6.1.4.1.3764.1.1.200.20.90.70.1',
  'loIeRow' => '1.3.6.1.4.1.3764.1.1.200.20.90.70.1.1',
  'loDriveTable' => '1.3.6.1.4.1.3764.1.1.200.20.90.80',
  'loDriveEntry' => '1.3.6.1.4.1.3764.1.1.200.20.90.80.1',
  'loDriveRow' => '1.3.6.1.4.1.3764.1.1.200.20.90.80.1.1',
  'loStatisticsTable' => '1.3.6.1.4.1.3764.1.1.200.20.90.90',
  'loStatisticsEntry' => '1.3.6.1.4.1.3764.1.1.200.20.90.90.1',
  'loNumRecoveredGets' => '1.3.6.1.4.1.3764.1.1.200.20.90.90.1.1',
  'loNumRecoveredPuts' => '1.3.6.1.4.1.3764.1.1.200.20.90.90.1.2',
  'loNumRecoveredScans' => '1.3.6.1.4.1.3764.1.1.200.20.90.90.1.3',
  'loStatsNumPuts' => '1.3.6.1.4.1.3764.1.1.200.20.90.90.1.4',
  'loStatsNumPutRetries' => '1.3.6.1.4.1.3764.1.1.200.20.90.90.1.5',
  'loStatsNumGetRetries' => '1.3.6.1.4.1.3764.1.1.200.20.90.90.1.6',
  'loStatsNumScanRetries' => '1.3.6.1.4.1.3764.1.1.200.20.90.90.1.7',
  'ras' => '1.3.6.1.4.1.3764.1.1.200.20.100',
  'rasSystemStatusTable' => '1.3.6.1.4.1.3764.1.1.200.20.100.10',
  'rasSystemStatusEntry' => '1.3.6.1.4.1.3764.1.1.200.20.100.10.1',
  'rasStatusGroupIndex' => '1.3.6.1.4.1.3764.1.1.200.20.100.10.1.1',
  'rasStatusGroupIndexDefinition' => 'ADIC-MANAGEMENT-MIB::AdicStatusGroup',
  'rasStatusGroupStatus' => '1.3.6.1.4.1.3764.1.1.200.20.100.10.1.2',
  'rasStatusGroupStatusDefinition' => 'ADIC-MANAGEMENT-MIB::AdicStatusGroupState',
  'rasStatusGroupPreviousStatus' => '1.3.6.1.4.1.3764.1.1.200.20.100.10.1.3',
  'rasStatusGroupPreviousStatusDefinition' => 'ADIC-MANAGEMENT-MIB::AdicStatusGroupState',
  'rasStatusGroupTextSummary' => '1.3.6.1.4.1.3764.1.1.200.20.100.10.1.4',
  'rasStatusGroupTotalTickets' => '1.3.6.1.4.1.3764.1.1.200.20.100.10.1.5',
  'rasStatusGroupOpenTickets' => '1.3.6.1.4.1.3764.1.1.200.20.100.10.1.6',
  'rasStatusGroupActionsPending' => '1.3.6.1.4.1.3764.1.1.200.20.100.10.1.7',
  'rasStatusGroupLastChange' => '1.3.6.1.4.1.3764.1.1.200.20.100.10.1.8',
  'rasStatusGroupLastChangeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicDateAndTime',
  'rasTicketTable' => '1.3.6.1.4.1.3764.1.1.200.20.100.20',
  'rasTicketEntry' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1',
  'rasTicketId' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.1',
  'rasTicketRowStatus' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.2',
  'rasTicketRowStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::RowStatus',
  'rasTicketState' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.3',
  'rasTicketStateDefinition' => 'ADIC-MANAGEMENT-MIB::AdicRasTicketState',
  'rasTicketQualifier' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.4',
  'rasTicketQualifierDefinition' => {
    '1' => 'none',
    '2' => 'resolved',
    '3' => 'cannotDuplicate',
    '4' => 'asDesigned',
    '5' => 'manualOverride',
  },
  'rasTicketSeverity' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.5',
  'rasTicketSeverityDefinition' => 'ADIC-MANAGEMENT-MIB::AdicRasTicketSeverity',
  'rasTicketDescription' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.6',
  'rasTicketStatusGroup' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.7',
  'rasTicketStatusGroupDefinition' => 'ADIC-MANAGEMENT-MIB::AdicStatusGroup',
  'rasTicketGroupStatus' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.8',
  'rasTicketGroupStatusDefinition' => 'ADIC-MANAGEMENT-MIB::AdicStatusGroupState',
  'rasTicketClosedBy' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.9',
  'rasTicketVerifiedBy' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.10',
  'rasTicketComments' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.11',
  'rasTicketSerialNumber' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.12',
  'rasTicketTimeOpened' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.13',
  'rasTicketTimeOpenedDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicDateAndTime',
  'rasTicketTimeClosed' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.14',
  'rasTicketTimeClosedDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicDateAndTime',
  'rasTicketCount' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.15',
  'rasTicketKeyReport' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.16',
  'rasTicketEventCode' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.17',
  'rasReportTable' => '1.3.6.1.4.1.3764.1.1.200.20.100.30',
  'rasReportEntry' => '1.3.6.1.4.1.3764.1.1.200.20.100.30.1',
  'rasReportId' => '1.3.6.1.4.1.3764.1.1.200.20.100.30.1.1',
  'rasReportRowStatus' => '1.3.6.1.4.1.3764.1.1.200.20.100.30.1.2',
  'rasReportRowStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::RowStatus',
  'rasReportTimestamp' => '1.3.6.1.4.1.3764.1.1.200.20.100.30.1.3',
  'rasReportTimestampDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicDateAndTime',
  'rasReportStatusGroup' => '1.3.6.1.4.1.3764.1.1.200.20.100.30.1.4',
  'rasReportStatusGroupDefinition' => 'ADIC-MANAGEMENT-MIB::AdicStatusGroup',
  'rasReportOrcData' => '1.3.6.1.4.1.3764.1.1.200.20.100.30.1.5',
  'rasReportGroupStatus' => '1.3.6.1.4.1.3764.1.1.200.20.100.30.1.6',
  'rasReportGroupStatusDefinition' => 'ADIC-MANAGEMENT-MIB::AdicStatusGroupState',
  'rasReportDescription' => '1.3.6.1.4.1.3764.1.1.200.20.100.30.1.7',
  'rasReportOrcDescription' => '1.3.6.1.4.1.3764.1.1.200.20.100.30.1.8',
  'rasReportRepeatCounter' => '1.3.6.1.4.1.3764.1.1.200.20.100.30.1.9',
  'rasReportSerialNumber' => '1.3.6.1.4.1.3764.1.1.200.20.100.30.1.10',
  'rasReportHeadReport' => '1.3.6.1.4.1.3764.1.1.200.20.100.30.1.11',
  'rasFruStatTable' => '1.3.6.1.4.1.3764.1.1.200.20.100.50',
  'rasFruStatEntry' => '1.3.6.1.4.1.3764.1.1.200.20.100.50.1',
  'rasFruStatIndex' => '1.3.6.1.4.1.3764.1.1.200.20.100.50.1.1',
  'rasFruInstanceId' => '1.3.6.1.4.1.3764.1.1.200.20.100.50.1.2',
  'rasFruStatStatusGroup' => '1.3.6.1.4.1.3764.1.1.200.20.100.50.1.3',
  'rasFruStatStatusGroupDefinition' => 'ADIC-MANAGEMENT-MIB::AdicStatusGroup',
  'rasFruStatFruCategory' => '1.3.6.1.4.1.3764.1.1.200.20.100.50.1.4',
  'rasFruStatFruCategoryDefinition' => 'ADIC-MANAGEMENT-MIB::AdicRasFruCategory',
  'rasFruStatFruId' => '1.3.6.1.4.1.3764.1.1.200.20.100.50.1.5',
  'rasFruStatFirstReportTime' => '1.3.6.1.4.1.3764.1.1.200.20.100.50.1.6',
  'rasFruStatFirstReportTimeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicDateAndTime',
  'rasFruStatLastReportTime' => '1.3.6.1.4.1.3764.1.1.200.20.100.50.1.7',
  'rasFruStatLastReportTimeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicDateAndTime',
  'rasFruStatTotalTickets' => '1.3.6.1.4.1.3764.1.1.200.20.100.50.1.8',
  'rasFruStatOpenTickets' => '1.3.6.1.4.1.3764.1.1.200.20.100.50.1.9',
  'rasFruStatSerialNumber' => '1.3.6.1.4.1.3764.1.1.200.20.100.50.1.10',
  'rasFruStatState' => '1.3.6.1.4.1.3764.1.1.200.20.100.50.1.11',
  'rasFruStatStateDefinition' => {
    '1' => 'current',
    '2' => 'old',
  },
  'rasTicketFilterTable' => '1.3.6.1.4.1.3764.1.1.200.20.100.60',
  'rasTicketFilterEntry' => '1.3.6.1.4.1.3764.1.1.200.20.100.60.1',
  'rasTicketFilterStatusGroup' => '1.3.6.1.4.1.3764.1.1.200.20.100.60.1.1',
  'rasTicketFilterStatusGroupDefinition' => 'ADIC-MANAGEMENT-MIB::AdicStatusGroup',
  'rasTicketFilterState' => '1.3.6.1.4.1.3764.1.1.200.20.100.60.1.2',
  'rasTicketFilterStateDefinition' => 'ADIC-MANAGEMENT-MIB::AdicRasTicketState',
  'rasTicketFilterSeverity' => '1.3.6.1.4.1.3764.1.1.200.20.100.60.1.3',
  'rasTicketFilterSeverityDefinition' => 'ADIC-MANAGEMENT-MIB::AdicRasTicketSeverity',
};

$Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{'ADIC-MANAGEMENT-MIB::1.45'} = {
  'MIBVERSION' => '1.45',
  'AdicRasFruCategory' => {
    '1' => 'firmware',
    '2' => 'pcba',
    '3' => 'fan',
    '4' => 'accessor',
    '5' => 'picker',
    '6' => 'power',
    '7' => 'cable',
    '8' => 'mailbox',
    '9' => 'drive',
    '10' => 'media',
    '11' => 'label',
    '12' => 'hardware',
    '13' => 'environmental',
    '14' => 'interface',
    '15' => 'process',
    '16' => 'gen2robot',
    '17' => 'tower',
  },
  'AdicDateAndTime' => sub {
    my $value = shift;
    use Time::Local;
    if ($value && ($value =~ /^0x((\w{2} ){8,})/ || $value =~ /^((\w{2} ){8,})/)) {
      $value = $1;
      $value =~ s/ //g;
      my $year = hex substr($value, 0, 4);
      $value = substr($value, 4);
      my ($month, $day, $hour, $minute, $second,
          $dseconds, $dirutc, $hoursutc, $minutesutc) = unpack "C*", pack "H*", $value;
      return timegm($second, $minute, $hour, $day, $month-1, $year-1900);
    } elsif ($value && unpack("H22", $value) =~ /(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})/) {
      my $year = hex $1.$2;
      my ($month, $day, $hour, $minute, $second,
          $dseconds, $dirutc, $hoursutc, $minutesutc) =
          map { hex($_) } ($3, $4, $5, $6, $7, $8, $9, $10, $11);
      return timegm($second, $minute, $hour, $day, $month-1, $year-1900);
    }
    return $value;
  },
  'AdicStatusGroupState' => {
    '1' => 'good',
    '2' => 'failed',
    '3' => 'degraded',
    '4' => 'warning',
    '5' => 'informational',
    '6' => 'unknown',
    '7' => 'invalid',
  },
  'AdicSegmentType' => {
    '1' => 'gripper',
    '2' => 'storage',
    '3' => 'ie',
    '4' => 'drive',
  },
  'AdicRasTicketState' => {
    '1' => 'new',
    '2' => 'open',
    '3' => 'suspended',
    '4' => 'closed',
    '5' => 'verified',
    '99' => 'all',
  },
  'AdicEthernetSpeed' => {
    '1' => 'baseT10',
    '2' => 'baseT100',
  },
  'AdicFcPortSpeed' => {
    '1' => 'auto',
    '1000' => 'megabits1000',
    '2000' => 'megabits2000',
    '4000' => 'megabits4000',
    '8000' => 'megabits8000',
  },
  'AdicRasTicketPriority' => {
    '1' => 'high',
    '2' => 'medium',
    '3' => 'low',
  },
  'AdicInstallStatus' => {
    '1' => 'ok',
    '2' => 'inProgress',
    '3' => 'failed',
    '4' => 'updateAborted',
  },
  'AdicControllerRole' => {
    '1' => 'master',
    '2' => 'slave',
  },
  'AdicStatusGroup' => {
    '1' => 'connectivity',
    '2' => 'control',
    '3' => 'media',
    '4' => 'drives',
    '5' => 'powerAndCooling',
    '6' => 'robotics',
    '99' => 'all',
  },
  'AdicFcPortType' => {
    '1' => 'auto',
    '2' => 'nPort',
    '3' => 'nlPort',
  },
  'AdicRasTicketSeverity' => {
    '1' => 'critical',
    '2' => 'degraded',
    '3' => 'warning',
    '4' => 'minor',
    '5' => 'informational',
  },
};

$Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{'ADIC-MANAGEMENT-MIB::1.93'} = {
  'enterprises' => '1.3.6.1.4.1',
  'hardware' => '1.3.6.1.4.1.3764.1.1.200',
  'management' => '1.3.6.1.4.1.3764.1.1.200.20',
  'globalStatus' => '1.3.6.1.4.1.3764.1.1.200.20.10',
  'globalStatusTable' => '1.3.6.1.4.1.3764.1.1.200.20.10.10',
  'globalStatusEntry' => '1.3.6.1.4.1.3764.1.1.200.20.10.10.1',
  'role' => '1.3.6.1.4.1.3764.1.1.200.20.10.10.1.1',
  'roleDefinition' => {
    '1' => 'master',
    '2' => 'slave',
  },
  'status' => '1.3.6.1.4.1.3764.1.1.200.20.10.10.1.2',
  'statusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicAgentStatus',
  'systemDateAndTime' => '1.3.6.1.4.1.3764.1.1.200.20.10.10.1.3',
  'systemDateAndTimeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicDateAndTime',
  'networkTimeServer1' => '1.3.6.1.4.1.3764.1.1.200.20.10.10.1.4',
  'networkTimeProtocol' => '1.3.6.1.4.1.3764.1.1.200.20.10.10.1.5',
  'networkTimeProtocolDefinition' => {
    '1' => 'ntp',
  },
  'networkTimeEnable' => '1.3.6.1.4.1.3764.1.1.200.20.10.10.1.6',
  'networkTimeEnableDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicEnable',
  'enableDaylightSavingsTime' => '1.3.6.1.4.1.3764.1.1.200.20.10.10.1.8',
  'enableDaylightSavingsTimeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicEnable',
  'networkTimeServer2' => '1.3.6.1.4.1.3764.1.1.200.20.10.10.1.9',
  'globalEthernetManager' => '1.3.6.1.4.1.3764.1.1.200.20.15',
  'globalEthernetTable' => '1.3.6.1.4.1.3764.1.1.200.20.15.10',
  'globalEthernetEntry' => '1.3.6.1.4.1.3764.1.1.200.20.15.10.1',
  'mcbHostName' => '1.3.6.1.4.1.3764.1.1.200.20.15.10.1.1',
  'ipAddress' => '1.3.6.1.4.1.3764.1.1.200.20.15.10.1.2',
  'dhcpStatus' => '1.3.6.1.4.1.3764.1.1.200.20.15.10.1.3',
  'dhcpStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicEnable',
  'ipAddressSubnetMask' => '1.3.6.1.4.1.3764.1.1.200.20.15.10.1.4',
  'speedAutoNegotiation' => '1.3.6.1.4.1.3764.1.1.200.20.15.10.1.5',
  'speedAutoNegotiationDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicEnable',
  'preferredSpeed' => '1.3.6.1.4.1.3764.1.1.200.20.15.10.1.6',
  'preferredSpeedDefinition' => 'ADIC-MANAGEMENT-MIB::AdicEthernetSpeed',
  'actualSpeed' => '1.3.6.1.4.1.3764.1.1.200.20.15.10.1.7',
  'actualSpeedDefinition' => 'ADIC-MANAGEMENT-MIB::AdicEthernetSpeed',
  'ethernetDuplex' => '1.3.6.1.4.1.3764.1.1.200.20.15.10.1.8',
  'ethernetDuplexDefinition' => {
    '1' => 'half',
    '2' => 'full',
  },
  'systemManager' => '1.3.6.1.4.1.3764.1.1.200.20.20',
  'systemManagerTable' => '1.3.6.1.4.1.3764.1.1.200.20.20.10',
  'systemManagerEntry' => '1.3.6.1.4.1.3764.1.1.200.20.20.10.1',
  'softwareComponentIndex' => '1.3.6.1.4.1.3764.1.1.200.20.20.10.1.1',
  'processRowStatus' => '1.3.6.1.4.1.3764.1.1.200.20.20.10.1.2',
  'processRowStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::RowStatus',
  'processPhysicalMemory' => '1.3.6.1.4.1.3764.1.1.200.20.20.10.1.3',
  'processResidentMemory' => '1.3.6.1.4.1.3764.1.1.200.20.20.10.1.4',
  'softwareInstallationTable' => '1.3.6.1.4.1.3764.1.1.200.20.20.20',
  'softwareInstallationEntry' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1',
  'installPackageName' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.1',
  'installProcessStatus' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.2',
  'installCommand' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.3',
  'installCommandDefinition' => {
    '1' => 'download',
    '2' => 'install',
    '3' => 'abort',
    '4' => 'timeEstimate',
  },
  'installStatusText' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.4',
  'currentFirmwareVersion' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.5',
  'previousFirmwareVersion' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.6',
  'downloadedFirmwareVersion' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.7',
  'mcbInstallStatusText' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.9',
  'cmbInstallStatusText' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.10',
  'rcuInstallStatusText' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.11',
  'fcbInstallStatusText' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.12',
  'amcInstallStatusText' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.13',
  'mcbInstallProcessStatus' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.14',
  'mcbInstallProcessStatusDefinition' => 'ADIC-MANAGEMENT-MIB::AdicInstallStatus',
  'cmbInstallProcessStatus' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.15',
  'cmbInstallProcessStatusDefinition' => 'ADIC-MANAGEMENT-MIB::AdicInstallStatus',
  'rcuInstallProcessStatus' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.16',
  'rcuInstallProcessStatusDefinition' => 'ADIC-MANAGEMENT-MIB::AdicInstallStatus',
  'fcbInstallProcessStatus' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.17',
  'fcbInstallProcessStatusDefinition' => 'ADIC-MANAGEMENT-MIB::AdicInstallStatus',
  'amcInstallProcessStatus' => '1.3.6.1.4.1.3764.1.1.200.20.20.20.1.18',
  'amcInstallProcessStatusDefinition' => 'ADIC-MANAGEMENT-MIB::AdicInstallStatus',
  'persistentData' => '1.3.6.1.4.1.3764.1.1.200.20.30',
  'persistentDataTable' => '1.3.6.1.4.1.3764.1.1.200.20.30.10',
  'persistentDataEntry' => '1.3.6.1.4.1.3764.1.1.200.20.30.10.1',
  'capacity' => '1.3.6.1.4.1.3764.1.1.200.20.30.10.1.1',
  'freeSpace' => '1.3.6.1.4.1.3764.1.1.200.20.30.10.1.2',
  'security' => '1.3.6.1.4.1.3764.1.1.200.20.40',
  'userTable' => '1.3.6.1.4.1.3764.1.1.200.20.40.20',
  'userEntry' => '1.3.6.1.4.1.3764.1.1.200.20.40.20.1',
  'userName' => '1.3.6.1.4.1.3764.1.1.200.20.40.20.1.1',
  'userRowStatus' => '1.3.6.1.4.1.3764.1.1.200.20.40.20.1.2',
  'userRowStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::RowStatus',
  'userGroup' => '1.3.6.1.4.1.3764.1.1.200.20.40.20.1.3',
  'userPassword' => '1.3.6.1.4.1.3764.1.1.200.20.40.20.1.4',
  'userLibAccessList' => '1.3.6.1.4.1.3764.1.1.200.20.40.20.1.5',
  'licensing' => '1.3.6.1.4.1.3764.1.1.200.20.50',
  'licenseKeyTable' => '1.3.6.1.4.1.3764.1.1.200.20.50.10',
  'licenseKeyEntry' => '1.3.6.1.4.1.3764.1.1.200.20.50.10.1',
  'licenseKeyIndex' => '1.3.6.1.4.1.3764.1.1.200.20.50.10.1.1',
  'licenseKeyRowStatus' => '1.3.6.1.4.1.3764.1.1.200.20.50.10.1.2',
  'licenseKeyRowStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::RowStatus',
  'key' => '1.3.6.1.4.1.3764.1.1.200.20.50.10.1.3',
  'licenseKeyDuration' => '1.3.6.1.4.1.3764.1.1.200.20.50.10.1.4',
  'licenseKeyDurationDefinition' => {
    '1' => 'permanent',
    '2' => 'transient',
  },
  'licenseKeyExpirationDate' => '1.3.6.1.4.1.3764.1.1.200.20.50.10.1.5',
  'licenseKeyExpirationDateDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicDateAndTime',
  'licenseKeyAppliedDate' => '1.3.6.1.4.1.3764.1.1.200.20.50.10.1.6',
  'licenseKeyAppliedDateDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicDateAndTime',
  'licenseFeatureTable' => '1.3.6.1.4.1.3764.1.1.200.20.50.20',
  'licenseFeatureEntry' => '1.3.6.1.4.1.3764.1.1.200.20.50.20.1',
  'licenseFeatureIndex' => '1.3.6.1.4.1.3764.1.1.200.20.50.20.1.1',
  'featureName' => '1.3.6.1.4.1.3764.1.1.200.20.50.20.1.2',
  'licenseFeatureQuantity' => '1.3.6.1.4.1.3764.1.1.200.20.50.20.1.3',
  'licensableFeatureTable' => '1.3.6.1.4.1.3764.1.1.200.20.50.30',
  'licensableFeatureEntry' => '1.3.6.1.4.1.3764.1.1.200.20.50.30.1',
  'licensableFeatureName' => '1.3.6.1.4.1.3764.1.1.200.20.50.30.1.1',
  'totalQuantityLicensed' => '1.3.6.1.4.1.3764.1.1.200.20.50.30.1.2',
  'eventManager' => '1.3.6.1.4.1.3764.1.1.200.20.70',
  'registrationTable' => '1.3.6.1.4.1.3764.1.1.200.20.70.10',
  'registrationEntry' => '1.3.6.1.4.1.3764.1.1.200.20.70.10.1',
  'hostIpAddress' => '1.3.6.1.4.1.3764.1.1.200.20.70.10.1.1',
  'udpPort' => '1.3.6.1.4.1.3764.1.1.200.20.70.10.1.2',
  'registrationRowStatus' => '1.3.6.1.4.1.3764.1.1.200.20.70.10.1.3',
  'registrationRowStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::RowStatus',
  'logTable' => '1.3.6.1.4.1.3764.1.1.200.20.70.20',
  'logEntry' => '1.3.6.1.4.1.3764.1.1.200.20.70.20.1',
  'logName' => '1.3.6.1.4.1.3764.1.1.200.20.70.20.1.1',
  'logSnapshotTable' => '1.3.6.1.4.1.3764.1.1.200.20.70.30',
  'logSnapshotEntry' => '1.3.6.1.4.1.3764.1.1.200.20.70.30.1',
  'logSnapshotCommand' => '1.3.6.1.4.1.3764.1.1.200.20.70.30.1.1',
  'logSnapshotCommandDefinition' => {
    '1' => 'retrieveLogs',
  },
  'physicalLibrary' => '1.3.6.1.4.1.3764.1.1.200.20.80',
  'phGeneralInfoTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.10',
  'phGeneralInfoEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1',
  'numElementDomains' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.1',
  'numPhSlots' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.2',
  'numPhIESlots' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.3',
  'numPhDrives' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.4',
  'onlineStatus' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.5',
  'onlineStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicOnlineStatus',
  'readiness' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.6',
  'readinessDefinition' => {
    '1' => 'ready',
    '2' => 'notReady',
  },
  'autoInventoryMode' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.7',
  'autoInventoryModeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicEnable',
  'autoCalibrateMode' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.8',
  'autoCalibrateModeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicEnable',
  'autoConfigureMode' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.9',
  'autoConfigureModeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicEnable',
  'numPhAisles' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.10',
  'operatingMode' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.11',
  'numStorageCartridges' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.12',
  'numCleaningCartridges' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.13',
  'physLibraryManagerLun' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.14',
  'physLibraryAutoCleaning' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.15',
  'physLibraryAutoCleaningDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicEnable',
  'physLibraryDoorStatus' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.16',
  'physLibraryDoorStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicDoorStatus',
  'numPhFrames' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.17',
  'totalRawCapacity' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.18',
  'totalFreeCapacity' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.19',
  'totalUsedCapacity' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.20',
  'logicalSNAdressingMode' => '1.3.6.1.4.1.3764.1.1.200.20.80.10.1.21',
  'logicalSNAdressingModeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicEnable',
  'mediaDomainTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.20',
  'mediaDomainEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.20.1',
  'mediaDomainIndex' => '1.3.6.1.4.1.3764.1.1.200.20.80.20.1.1',
  'mediaDomainName' => '1.3.6.1.4.1.3764.1.1.200.20.80.20.1.2',
  'numStorageElements' => '1.3.6.1.4.1.3764.1.1.200.20.80.20.1.3',
  'numIeElements' => '1.3.6.1.4.1.3764.1.1.200.20.80.20.1.4',
  'numCleaningSlots' => '1.3.6.1.4.1.3764.1.1.200.20.80.20.1.5',
  'mediaTypeTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.30',
  'mediaTypeEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.30.1',
  'mediaTypeIndex' => '1.3.6.1.4.1.3764.1.1.200.20.80.30.1.1',
  'mediaTypeName' => '1.3.6.1.4.1.3764.1.1.200.20.80.30.1.2',
  'numDriveElements' => '1.3.6.1.4.1.3764.1.1.200.20.80.30.1.3',
  'phFrameTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.41',
  'phFrameEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.41.1',
  'phFrameType' => '1.3.6.1.4.1.3764.1.1.200.20.80.41.1.1',
  'phFrameTypeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicComponentType',
  'phFrameSerialNumber' => '1.3.6.1.4.1.3764.1.1.200.20.80.41.1.2',
  'phFrameNumRacks' => '1.3.6.1.4.1.3764.1.1.200.20.80.41.1.3',
  'phSegmentTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.55',
  'phSegmentEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.55.1',
  'phSegmentAisle' => '1.3.6.1.4.1.3764.1.1.200.20.80.55.1.1',
  'phSegmentFrame' => '1.3.6.1.4.1.3764.1.1.200.20.80.55.1.2',
  'phSegmentRack' => '1.3.6.1.4.1.3764.1.1.200.20.80.55.1.3',
  'phSegmentSection' => '1.3.6.1.4.1.3764.1.1.200.20.80.55.1.4',
  'phSegmentCol' => '1.3.6.1.4.1.3764.1.1.200.20.80.55.1.5',
  'phSegmentStartingRow' => '1.3.6.1.4.1.3764.1.1.200.20.80.55.1.6',
  'phSegmentSize' => '1.3.6.1.4.1.3764.1.1.200.20.80.55.1.7',
  'phSegmentType' => '1.3.6.1.4.1.3764.1.1.200.20.80.55.1.8',
  'phSegmentTypeDefinition' => 'ADIC-MANAGEMENT-MIB::AdicSegmentType',
  'phSegmentMediaDomain' => '1.3.6.1.4.1.3764.1.1.200.20.80.55.1.9',
  'phSegmentStatus' => '1.3.6.1.4.1.3764.1.1.200.20.80.55.1.10',
  'phSegmentStatusDefinition' => {
    '1' => 'installed',
    '2' => 'notInstalled',
    '3' => 'reservedForCleaning',
  },
  'phSegmentCodStatus' => '1.3.6.1.4.1.3764.1.1.200.20.80.55.1.11',
  'phSegmentCodStatusDefinition' => {
    '1' => 'enabled',
    '2' => 'disabled',
    '3' => 'noCod',
  },
  'phSegStartingAddress' => '1.3.6.1.4.1.3764.1.1.200.20.80.55.1.12',
  'phStorageSegTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.60',
  'phStorageSegEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.60.1',
  'phStorageSegSize' => '1.3.6.1.4.1.3764.1.1.200.20.80.60.1.1',
  'phIeSegTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.70',
  'phIeSegEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.70.1',
  'phIeSegSize' => '1.3.6.1.4.1.3764.1.1.200.20.80.70.1.1',
  'phIeSegReserve' => '1.3.6.1.4.1.3764.1.1.200.20.80.70.1.2',
  'phIeSegReserveDefinition' => {
    '1' => 'reserve',
    '2' => 'release',
  },
  'phIeSegReservedBy' => '1.3.6.1.4.1.3764.1.1.200.20.80.70.1.3',
  'phIeSegOnlineStatus' => '1.3.6.1.4.1.3764.1.1.200.20.80.70.1.4',
  'phIeSegOnlineStatusDefinition' => {
    '1' => 'online',
    '2' => 'offline',
  },
  'phIeSegCommand' => '1.3.6.1.4.1.3764.1.1.200.20.80.70.1.5',
  'phIeSegCommandDefinition' => {
    '1' => 'import',
  },
  'phIeStationTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.75',
  'phIeStationEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.75.1',
  'phIeStationNumber' => '1.3.6.1.4.1.3764.1.1.200.20.80.75.1.1',
  'phIeStationDoorStatus' => '1.3.6.1.4.1.3764.1.1.200.20.80.75.1.2',
  'phIeStationDoorStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicDoorStatus',
  'phIeStationREDId' => '1.3.6.1.4.1.3764.1.1.200.20.80.75.1.3',
  'phIeStationREDIdDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicREDIdentifier',
  'phDriveSegTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.80',
  'phDriveSegEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.80.1',
  'phDriveSegSize' => '1.3.6.1.4.1.3764.1.1.200.20.80.80.1.1',
  'phDriveSegMediaType' => '1.3.6.1.4.1.3764.1.1.200.20.80.80.1.2',
  'phDriveSegInterfaceType' => '1.3.6.1.4.1.3764.1.1.200.20.80.80.1.3',
  'phDriveSegInterfaceTypeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicInterfaceType',
  'phCleaningSegTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.85',
  'phCleaningSegEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.85.1',
  'phCleaningSegSize' => '1.3.6.1.4.1.3764.1.1.200.20.80.85.1.1',
  'phCleaningSegRowStatus' => '1.3.6.1.4.1.3764.1.1.200.20.80.85.1.2',
  'phCleaningSegRowStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::RowStatus',
  'phStorageSlotTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.90',
  'phStorageSlotEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.90.1',
  'phStorageRow' => '1.3.6.1.4.1.3764.1.1.200.20.80.90.1.1',
  'phStorageElementAddr' => '1.3.6.1.4.1.3764.1.1.200.20.80.90.1.2',
  'phIeSlotTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.100',
  'phIeSlotEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.100.1',
  'phIeRow' => '1.3.6.1.4.1.3764.1.1.200.20.80.100.1.1',
  'phIeElementAddr' => '1.3.6.1.4.1.3764.1.1.200.20.80.100.1.2',
  'phIeMediaPresent' => '1.3.6.1.4.1.3764.1.1.200.20.80.100.1.3',
  'phIeMediaPresentDefinition' => {
    '1' => 'yes',
    '2' => 'no',
    '3' => 'error',
  },
  'phIeMediaId' => '1.3.6.1.4.1.3764.1.1.200.20.80.100.1.4',
  'phDriveTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.110',
  'phDriveEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1',
  'phDriveRow' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.1',
  'phDriveElementAddr' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.2',
  'phDriveScsiId' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.3',
  'phDriveScsiLun' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.4',
  'phDriveWwn' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.5',
  'phDriveVendor' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.6',
  'phDriveProduct' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.7',
  'phDriveSerialNumber' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.8',
  'phDriveNeedsCleaning' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.9',
  'phDriveNeedsCleaningDefinition' => {
    '1' => 'true',
    '2' => 'false',
    '3' => 'immediate',
  },
  'phDriveAutoCleaning' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.10',
  'phDriveAutoCleaningDefinition' => 'ADIC-MANAGEMENT-MIB::Boolean',
  'phDriveInterfaceType' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.11',
  'phDriveInterfaceTypeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicInterfaceType',
  'phDriveFcLoopId' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.12',
  'phDriveFcLoopIdMode' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.13',
  'phDriveFcLoopIdModeDefinition' => {
    '1' => 'soft',
    '2' => 'hard',
  },
  'phDriveFcHardId' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.14',
  'phDriveStatus' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.15',
  'phDriveStatusDefinition' => {
    '1' => 'loading',
    '2' => 'loaded',
    '3' => 'unloading',
    '4' => 'empty',
  },
  'phDriveCommand' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.16',
  'phDriveFcPortId' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.17',
  'phDriveCompressionOn' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.18',
  'phDriveCompressionOnDefinition' => 'ADIC-MANAGEMENT-MIB::Boolean',
  'phDriveWriteProtected' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.19',
  'phDriveWriteProtectedDefinition' => 'ADIC-MANAGEMENT-MIB::Boolean',
  'phDriveNumLoads' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.20',
  'phDriveNumCleans' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.21',
  'phDrivePowerStatus' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.22',
  'phDrivePowerStatusDefinition' => {
    '1' => 'poweredOn',
    '2' => 'poweredOff',
  },
  'phDriveReadErrors' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.23',
  'phDriveWriteErrors' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.24',
  'phDriveMbytesRead' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.25',
  'phDriveMbytesWritten' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.26',
  'phDriveFirmwareVersion' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.27',
  'phDriveREDId' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.28',
  'phDriveREDIdDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicREDIdentifier',
  'phDriveOnlineStatus' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.29',
  'phDriveOnlineStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicOnlineStatus',
  'phDriveErrorCodeBytes' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.30',
  'phDriveRasStatus' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.31',
  'phDriveRasStatusDefinition' => 'ADIC-MANAGEMENT-MIB::AdicStatusGroupState',
  'phDriveWwPortName' => '1.3.6.1.4.1.3764.1.1.200.20.80.110.1.32',
  'phDriveStatHistoryTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.112',
  'phDriveStatHistoryEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.112.1',
  'phHourIndex' => '1.3.6.1.4.1.3764.1.1.200.20.80.112.1.1',
  'phHourlyMBytesRead' => '1.3.6.1.4.1.3764.1.1.200.20.80.112.1.2',
  'phHourlyMBytesWritten' => '1.3.6.1.4.1.3764.1.1.200.20.80.112.1.3',
  'phHourlyMounts' => '1.3.6.1.4.1.3764.1.1.200.20.80.112.1.4',
  'phDrivePorts' => '1.3.6.1.4.1.3764.1.1.200.20.80.116',
  'fcDrivePortTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.116.10',
  'fcDrivePortEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.116.10.1',
  'fcPortPreferredSpeed' => '1.3.6.1.4.1.3764.1.1.200.20.80.116.10.1.1',
  'fcPortPreferredSpeedDefinition' => 'ADIC-MANAGEMENT-MIB::AdicFcPortSpeed',
  'fcPortNegotiatedSpeed' => '1.3.6.1.4.1.3764.1.1.200.20.80.116.10.1.2',
  'fcPortNegotiatedSpeedDefinition' => 'ADIC-MANAGEMENT-MIB::AdicFcPortSpeed',
  'fcPortPreferredType' => '1.3.6.1.4.1.3764.1.1.200.20.80.116.10.1.3',
  'fcPortPreferredTypeDefinition' => 'ADIC-MANAGEMENT-MIB::AdicFcPortType',
  'fcPortNegotiatedType' => '1.3.6.1.4.1.3764.1.1.200.20.80.116.10.1.4',
  'fcPortNegotiatedTypeDefinition' => 'ADIC-MANAGEMENT-MIB::AdicFcPortType',
  'fcPortTypeQualifier' => '1.3.6.1.4.1.3764.1.1.200.20.80.116.10.1.5',
  'fcPortTypeQualifierDefinition' => {
    '1' => 'public',
    '2' => 'private',
  },
  'phMediaTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.120',
  'phMediaEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.120.1',
  'phMediaBarCode' => '1.3.6.1.4.1.3764.1.1.200.20.80.120.1.1',
  'phMediaDomain' => '1.3.6.1.4.1.3764.1.1.200.20.80.120.1.2',
  'phMediaType' => '1.3.6.1.4.1.3764.1.1.200.20.80.120.1.3',
  'phMediaElementAddress' => '1.3.6.1.4.1.3764.1.1.200.20.80.120.1.4',
  'phMediaMounts' => '1.3.6.1.4.1.3764.1.1.200.20.80.120.1.5',
  'phMediaReadErrors' => '1.3.6.1.4.1.3764.1.1.200.20.80.120.1.6',
  'phMediaWriteErrors' => '1.3.6.1.4.1.3764.1.1.200.20.80.120.1.7',
  'phMediaCapacity' => '1.3.6.1.4.1.3764.1.1.200.20.80.120.1.8',
  'phMediaFreeSpace' => '1.3.6.1.4.1.3764.1.1.200.20.80.120.1.9',
  'phMediaExported' => '1.3.6.1.4.1.3764.1.1.200.20.80.120.1.10',
  'phMediaExportedDefinition' => 'ADIC-MANAGEMENT-MIB::Boolean',
  'phMediaImportTimestamp' => '1.3.6.1.4.1.3764.1.1.200.20.80.120.1.11',
  'phMediaImportTimestampDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicDateAndTime',
  'phMediaExportTimestamp' => '1.3.6.1.4.1.3764.1.1.200.20.80.120.1.12',
  'phMediaExportTimestampDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicDateAndTime',
  'phTransportTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.130',
  'phTransportEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.130.1',
  'phTransportElementAddress' => '1.3.6.1.4.1.3764.1.1.200.20.80.130.1.1',
  'phTransportNumRecoveredGets' => '1.3.6.1.4.1.3764.1.1.200.20.80.130.1.2',
  'phTransportNumRecoveredPuts' => '1.3.6.1.4.1.3764.1.1.200.20.80.130.1.3',
  'phTransportNumRecoveredScans' => '1.3.6.1.4.1.3764.1.1.200.20.80.130.1.4',
  'phTransportNumPuts' => '1.3.6.1.4.1.3764.1.1.200.20.80.130.1.5',
  'phTransportREDId' => '1.3.6.1.4.1.3764.1.1.200.20.80.130.1.6',
  'phTransportREDIdDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicREDIdentifier',
  'phTransportDomainTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.132',
  'phTransportDomainEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.132.1',
  'phTransportDomainIndex' => '1.3.6.1.4.1.3764.1.1.200.20.80.132.1.1',
  'phCleaningMediaTable' => '1.3.6.1.4.1.3764.1.1.200.20.80.140',
  'phCleaningMediaEntry' => '1.3.6.1.4.1.3764.1.1.200.20.80.140.1',
  'phCleaningMediaRow' => '1.3.6.1.4.1.3764.1.1.200.20.80.140.1.1',
  'phCleaningMediaStatus' => '1.3.6.1.4.1.3764.1.1.200.20.80.140.1.2',
  'phCleaningMediaStatusDefinition' => {
    '1' => 'allocated',
    '2' => 'unallocated',
  },
  'phCleaningMediaTypeIndex' => '1.3.6.1.4.1.3764.1.1.200.20.80.140.1.3',
  'phCleaningMediaVendorId' => '1.3.6.1.4.1.3764.1.1.200.20.80.140.1.4',
  'phCleaningMediaBarcode' => '1.3.6.1.4.1.3764.1.1.200.20.80.140.1.5',
  'phCleaningMediaUseCount' => '1.3.6.1.4.1.3764.1.1.200.20.80.140.1.6',
  'phCleaningMediaMaxUses' => '1.3.6.1.4.1.3764.1.1.200.20.80.140.1.7',
  'phCleaningMediaImportTimestamp' => '1.3.6.1.4.1.3764.1.1.200.20.80.140.1.8',
  'phCleaningMediaImportTimestampDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicDateAndTime',
  'logicalLibrary' => '1.3.6.1.4.1.3764.1.1.200.20.90',
  'loGeneralInfoTable' => '1.3.6.1.4.1.3764.1.1.200.20.90.10',
  'loGeneralInfoEntry' => '1.3.6.1.4.1.3764.1.1.200.20.90.10.1',
  'maxLogicalLibraries' => '1.3.6.1.4.1.3764.1.1.200.20.90.10.1.1',
  'numLogicalLibraries' => '1.3.6.1.4.1.3764.1.1.200.20.90.10.1.2',
  'masterOnlineStatus' => '1.3.6.1.4.1.3764.1.1.200.20.90.10.1.3',
  'masterOnlineStatusDefinition' => {
    '1' => 'online',
    '2' => 'offline',
  },
  'numVendorIds' => '1.3.6.1.4.1.3764.1.1.200.20.90.10.1.4',
  'autoPartitionTable' => '1.3.6.1.4.1.3764.1.1.200.20.90.12',
  'autoPartitionEntry' => '1.3.6.1.4.1.3764.1.1.200.20.90.12.1',
  'numAutoPartition' => '1.3.6.1.4.1.3764.1.1.200.20.90.12.1.1',
  'autoPartitionCommand' => '1.3.6.1.4.1.3764.1.1.200.20.90.12.1.2',
  'autoPartitionCommandDefinition' => {
    '1' => 'autoPartition',
  },
  'vendorIdTable' => '1.3.6.1.4.1.3764.1.1.200.20.90.15',
  'vendorIdEntry' => '1.3.6.1.4.1.3764.1.1.200.20.90.15.1',
  'vendorIdIndex' => '1.3.6.1.4.1.3764.1.1.200.20.90.15.1.1',
  'vendorName' => '1.3.6.1.4.1.3764.1.1.200.20.90.15.1.2',
  'numProductIds' => '1.3.6.1.4.1.3764.1.1.200.20.90.15.1.3',
  'productIdTable' => '1.3.6.1.4.1.3764.1.1.200.20.90.17',
  'productIdEntry' => '1.3.6.1.4.1.3764.1.1.200.20.90.17.1',
  'productIdIndex' => '1.3.6.1.4.1.3764.1.1.200.20.90.17.1.1',
  'productIdName' => '1.3.6.1.4.1.3764.1.1.200.20.90.17.1.2',
  'productDrivesMin' => '1.3.6.1.4.1.3764.1.1.200.20.90.17.1.3',
  'productDrivesMax' => '1.3.6.1.4.1.3764.1.1.200.20.90.17.1.4',
  'productSlotsMin' => '1.3.6.1.4.1.3764.1.1.200.20.90.17.1.5',
  'productSlotsMax' => '1.3.6.1.4.1.3764.1.1.200.20.90.17.1.6',
  'productIeMin' => '1.3.6.1.4.1.3764.1.1.200.20.90.17.1.7',
  'productIeMax' => '1.3.6.1.4.1.3764.1.1.200.20.90.17.1.8',
  'logicalLibraryTable' => '1.3.6.1.4.1.3764.1.1.200.20.90.20',
  'logicalLibraryEntry' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1',
  'logicalLibraryIndex' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.1',
  'command' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.2',
  'commandDefinition' => {
    '1' => 'createSimple',
    '2' => 'createExpert',
    '3' => 'modify',
    '4' => 'delete',
  },
  'name' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.3',
  'assignedLun' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.4',
  'vendorId' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.5',
  'productId' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.6',
  'mediaDomain' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.7',
  'mediaType' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.8',
  'numSlots' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.9',
  'numIE' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.10',
  'numDrives' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.11',
  'loStatus' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.12',
  'loStatusDefinition' => {
    '1' => 'online',
    '2' => 'offline',
  },
  'automaticCleaning' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.13',
  'automaticCleaningDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicEnable',
  'mediaTypeChecking' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.14',
  'mediaTypeCheckingDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicEnable',
  'serialNumber' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.15',
  'loInterfaceType' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.16',
  'loInterfaceTypeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicInterfaceType',
  'loNumLibraries' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.17',
  'loLtoTapeTags' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.18',
  'loLtoTapeTagsDefinition' => {
    '1' => 'prefix',
    '2' => 'suffix',
    '3' => 'disabled',
  },
  'loMediaTypeCheckingPolicy' => '1.3.6.1.4.1.3764.1.1.200.20.90.20.1.19',
  'loSegmentTable' => '1.3.6.1.4.1.3764.1.1.200.20.90.25',
  'loSegmentEntry' => '1.3.6.1.4.1.3764.1.1.200.20.90.25.1',
  'loSegmentAisle' => '1.3.6.1.4.1.3764.1.1.200.20.90.25.1.1',
  'loSegmentFrame' => '1.3.6.1.4.1.3764.1.1.200.20.90.25.1.2',
  'loSegmentRack' => '1.3.6.1.4.1.3764.1.1.200.20.90.25.1.3',
  'loSegmentSection' => '1.3.6.1.4.1.3764.1.1.200.20.90.25.1.4',
  'loSegmentCol' => '1.3.6.1.4.1.3764.1.1.200.20.90.25.1.5',
  'loSegmentStartingRow' => '1.3.6.1.4.1.3764.1.1.200.20.90.25.1.6',
  'loSegmentSize' => '1.3.6.1.4.1.3764.1.1.200.20.90.25.1.7',
  'loSegmentType' => '1.3.6.1.4.1.3764.1.1.200.20.90.25.1.8',
  'loSegmentTypeDefinition' => 'ADIC-MANAGEMENT-MIB::AdicSegmentType',
  'loSegmentMediaDomain' => '1.3.6.1.4.1.3764.1.1.200.20.90.25.1.9',
  'loSegmentBelongsTo' => '1.3.6.1.4.1.3764.1.1.200.20.90.25.1.10',
  'loSegmentCommand' => '1.3.6.1.4.1.3764.1.1.200.20.90.25.1.11',
  'loSegmentCommandDefinition' => {
    '1' => 'allocate',
    '2' => 'free',
    '3' => 'reserveForCleaning',
  },
  'loSegmentStatus' => '1.3.6.1.4.1.3764.1.1.200.20.90.25.1.12',
  'loSegmentStatusDefinition' => {
    '1' => 'allocated',
    '2' => 'unallocated',
  },
  'loSegmentStartingAddress' => '1.3.6.1.4.1.3764.1.1.200.20.90.25.1.13',
  'loSegmentBelongsToTable' => '1.3.6.1.4.1.3764.1.1.200.20.90.27',
  'loSegmentBelongsToEntry' => '1.3.6.1.4.1.3764.1.1.200.20.90.27.1',
  'loSegmentAssignedTo' => '1.3.6.1.4.1.3764.1.1.200.20.90.27.1.1',
  'loStorageSegTable' => '1.3.6.1.4.1.3764.1.1.200.20.90.30',
  'loStorageSegEntry' => '1.3.6.1.4.1.3764.1.1.200.20.90.30.1',
  'loStorageSegSize' => '1.3.6.1.4.1.3764.1.1.200.20.90.30.1.1',
  'loStorageSegStartingAddress' => '1.3.6.1.4.1.3764.1.1.200.20.90.30.1.2',
  'loIeSegTable' => '1.3.6.1.4.1.3764.1.1.200.20.90.40',
  'loIeSegEntry' => '1.3.6.1.4.1.3764.1.1.200.20.90.40.1',
  'loIeSegSize' => '1.3.6.1.4.1.3764.1.1.200.20.90.40.1.1',
  'loIeSegReserve' => '1.3.6.1.4.1.3764.1.1.200.20.90.40.1.2',
  'loIeSegReserveDefinition' => {
    '1' => 'reserve',
    '2' => 'release',
  },
  'loIeSegReservedBy' => '1.3.6.1.4.1.3764.1.1.200.20.90.40.1.3',
  'loIeSegStartingAddress' => '1.3.6.1.4.1.3764.1.1.200.20.90.40.1.4',
  'loDriveSegTable' => '1.3.6.1.4.1.3764.1.1.200.20.90.50',
  'loDriveSegEntry' => '1.3.6.1.4.1.3764.1.1.200.20.90.50.1',
  'loDriveSegSize' => '1.3.6.1.4.1.3764.1.1.200.20.90.50.1.1',
  'loDriveSegStartingAddress' => '1.3.6.1.4.1.3764.1.1.200.20.90.50.1.2',
  'loDriveSegMediaType' => '1.3.6.1.4.1.3764.1.1.200.20.90.50.1.3',
  'loDriveSegInterfaceType' => '1.3.6.1.4.1.3764.1.1.200.20.90.50.1.4',
  'loDriveSegInterfaceTypeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicInterfaceType',
  'loStorageSlotTable' => '1.3.6.1.4.1.3764.1.1.200.20.90.60',
  'loStorageSlotEntry' => '1.3.6.1.4.1.3764.1.1.200.20.90.60.1',
  'loStorageRow' => '1.3.6.1.4.1.3764.1.1.200.20.90.60.1.1',
  'loIeSlotTable' => '1.3.6.1.4.1.3764.1.1.200.20.90.70',
  'loIeSlotEntry' => '1.3.6.1.4.1.3764.1.1.200.20.90.70.1',
  'loIeRow' => '1.3.6.1.4.1.3764.1.1.200.20.90.70.1.1',
  'loDriveTable' => '1.3.6.1.4.1.3764.1.1.200.20.90.80',
  'loDriveEntry' => '1.3.6.1.4.1.3764.1.1.200.20.90.80.1',
  'loDriveRow' => '1.3.6.1.4.1.3764.1.1.200.20.90.80.1.1',
  'loStatisticsTable' => '1.3.6.1.4.1.3764.1.1.200.20.90.90',
  'loStatisticsEntry' => '1.3.6.1.4.1.3764.1.1.200.20.90.90.1',
  'loNumRecoveredGets' => '1.3.6.1.4.1.3764.1.1.200.20.90.90.1.1',
  'loNumRecoveredPuts' => '1.3.6.1.4.1.3764.1.1.200.20.90.90.1.2',
  'loNumRecoveredScans' => '1.3.6.1.4.1.3764.1.1.200.20.90.90.1.3',
  'loStatsNumPuts' => '1.3.6.1.4.1.3764.1.1.200.20.90.90.1.4',
  'loStatsNumPutRetries' => '1.3.6.1.4.1.3764.1.1.200.20.90.90.1.5',
  'loStatsNumGetRetries' => '1.3.6.1.4.1.3764.1.1.200.20.90.90.1.6',
  'loStatsNumScanRetries' => '1.3.6.1.4.1.3764.1.1.200.20.90.90.1.7',
  'ras' => '1.3.6.1.4.1.3764.1.1.200.20.100',
  'rasSystemStatusTable' => '1.3.6.1.4.1.3764.1.1.200.20.100.10',
  'rasSystemStatusEntry' => '1.3.6.1.4.1.3764.1.1.200.20.100.10.1',
  'rasStatusGroupIndex' => '1.3.6.1.4.1.3764.1.1.200.20.100.10.1.1',
  'rasStatusGroupIndexDefinition' => 'ADIC-MANAGEMENT-MIB::AdicStatusGroup',
  'rasStatusGroupStatus' => '1.3.6.1.4.1.3764.1.1.200.20.100.10.1.2',
  'rasStatusGroupStatusDefinition' => 'ADIC-MANAGEMENT-MIB::AdicStatusGroupState',
  'rasStatusGroupPreviousStatus' => '1.3.6.1.4.1.3764.1.1.200.20.100.10.1.3',
  'rasStatusGroupPreviousStatusDefinition' => 'ADIC-MANAGEMENT-MIB::AdicStatusGroupState',
  'rasStatusGroupTextSummary' => '1.3.6.1.4.1.3764.1.1.200.20.100.10.1.4',
  'rasStatusGroupTotalTickets' => '1.3.6.1.4.1.3764.1.1.200.20.100.10.1.5',
  'rasStatusGroupOpenTickets' => '1.3.6.1.4.1.3764.1.1.200.20.100.10.1.6',
  'rasStatusGroupActionsPending' => '1.3.6.1.4.1.3764.1.1.200.20.100.10.1.7',
  'rasStatusGroupLastChange' => '1.3.6.1.4.1.3764.1.1.200.20.100.10.1.8',
  'rasStatusGroupLastChangeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicDateAndTime',
  'rasTicketTable' => '1.3.6.1.4.1.3764.1.1.200.20.100.20',
  'rasTicketEntry' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1',
  'rasTicketId' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.1',
  'rasTicketRowStatus' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.2',
  'rasTicketRowStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::RowStatus',
  'rasTicketState' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.3',
  'rasTicketStateDefinition' => 'ADIC-MANAGEMENT-MIB::AdicRasTicketState',
  'rasTicketQualifier' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.4',
  'rasTicketQualifierDefinition' => {
    '1' => 'none',
    '2' => 'resolved',
    '3' => 'cannotDuplicate',
    '4' => 'asDesigned',
    '5' => 'manualOverride',
  },
  'rasTicketPriority' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.5',
  'rasTicketDescription' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.6',
  'rasTicketStatusGroup' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.7',
  'rasTicketStatusGroupDefinition' => 'ADIC-MANAGEMENT-MIB::AdicStatusGroup',
  'rasTicketGroupStatus' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.8',
  'rasTicketGroupStatusDefinition' => 'ADIC-MANAGEMENT-MIB::AdicStatusGroupState',
  'rasTicketClosedBy' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.9',
  'rasTicketVerifiedBy' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.10',
  'rasTicketComments' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.11',
  'rasTicketSerialNumber' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.12',
  'rasTicketTimeOpened' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.13',
  'rasTicketTimeOpenedDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicDateAndTime',
  'rasTicketTimeClosed' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.14',
  'rasTicketTimeClosedDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicDateAndTime',
  'rasTicketCount' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.15',
  'rasTicketKeyReport' => '1.3.6.1.4.1.3764.1.1.200.20.100.20.1.16',
  'rasReportTable' => '1.3.6.1.4.1.3764.1.1.200.20.100.30',
  'rasReportEntry' => '1.3.6.1.4.1.3764.1.1.200.20.100.30.1',
  'rasReportId' => '1.3.6.1.4.1.3764.1.1.200.20.100.30.1.1',
  'rasReportRowStatus' => '1.3.6.1.4.1.3764.1.1.200.20.100.30.1.2',
  'rasReportRowStatusDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::RowStatus',
  'rasReportTimestamp' => '1.3.6.1.4.1.3764.1.1.200.20.100.30.1.3',
  'rasReportTimestampDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicDateAndTime',
  'rasReportStatusGroup' => '1.3.6.1.4.1.3764.1.1.200.20.100.30.1.4',
  'rasReportStatusGroupDefinition' => 'ADIC-MANAGEMENT-MIB::AdicStatusGroup',
  'rasReportOrcData' => '1.3.6.1.4.1.3764.1.1.200.20.100.30.1.5',
  'rasReportGroupStatus' => '1.3.6.1.4.1.3764.1.1.200.20.100.30.1.6',
  'rasReportGroupStatusDefinition' => 'ADIC-MANAGEMENT-MIB::AdicStatusGroupState',
  'rasReportDescription' => '1.3.6.1.4.1.3764.1.1.200.20.100.30.1.7',
  'rasReportOrcDescription' => '1.3.6.1.4.1.3764.1.1.200.20.100.30.1.8',
  'rasReportRepeatCounter' => '1.3.6.1.4.1.3764.1.1.200.20.100.30.1.9',
  'rasReportSerialNumber' => '1.3.6.1.4.1.3764.1.1.200.20.100.30.1.10',
  'rasReportHeadReport' => '1.3.6.1.4.1.3764.1.1.200.20.100.30.1.11',
  'rasFruStatTable' => '1.3.6.1.4.1.3764.1.1.200.20.100.50',
  'rasFruStatEntry' => '1.3.6.1.4.1.3764.1.1.200.20.100.50.1',
  'rasFruStatIndex' => '1.3.6.1.4.1.3764.1.1.200.20.100.50.1.1',
  'rasFruInstanceId' => '1.3.6.1.4.1.3764.1.1.200.20.100.50.1.2',
  'rasFruStatStatusGroup' => '1.3.6.1.4.1.3764.1.1.200.20.100.50.1.3',
  'rasFruStatStatusGroupDefinition' => 'ADIC-MANAGEMENT-MIB::AdicStatusGroup',
  'rasFruStatFruCategory' => '1.3.6.1.4.1.3764.1.1.200.20.100.50.1.4',
  'rasFruStatFruId' => '1.3.6.1.4.1.3764.1.1.200.20.100.50.1.5',
  'rasFruStatFirstReportTime' => '1.3.6.1.4.1.3764.1.1.200.20.100.50.1.6',
  'rasFruStatFirstReportTimeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicDateAndTime',
  'rasFruStatLastReportTime' => '1.3.6.1.4.1.3764.1.1.200.20.100.50.1.7',
  'rasFruStatLastReportTimeDefinition' => 'ADIC-INTELLIGENT-STORAGE-MIB::AdicDateAndTime',
  'rasFruStatTotalTickets' => '1.3.6.1.4.1.3764.1.1.200.20.100.50.1.8',
  'rasFruStatOpenTickets' => '1.3.6.1.4.1.3764.1.1.200.20.100.50.1.9',
  'rasFruStatSerialNumber' => '1.3.6.1.4.1.3764.1.1.200.20.100.50.1.10',
  'rasFruStatState' => '1.3.6.1.4.1.3764.1.1.200.20.100.50.1.11',
  'rasFruStatStateDefinition' => {
    '1' => 'current',
    '2' => 'old',
  },
  'rasTicketFilterTable' => '1.3.6.1.4.1.3764.1.1.200.20.100.60',
  'rasTicketFilterEntry' => '1.3.6.1.4.1.3764.1.1.200.20.100.60.1',
  'rasTicketFilterStatusGroup' => '1.3.6.1.4.1.3764.1.1.200.20.100.60.1.1',
  'rasTicketFilterStatusGroupDefinition' => 'ADIC-MANAGEMENT-MIB::AdicStatusGroup',
  'rasTicketFilterState' => '1.3.6.1.4.1.3764.1.1.200.20.100.60.1.2',
  'rasTicketFilterStateDefinition' => 'ADIC-MANAGEMENT-MIB::AdicRasTicketState',
  'rasTicketFilterSeverity' => '1.3.6.1.4.1.3764.1.1.200.20.100.60.1.3',
  'rasTicketFilterSeverityDefinition' => 'ADIC-MANAGEMENT-MIB::AdicRasTicketSeverity',
};

$Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{'ADIC-MANAGEMENT-MIB::1.93'} = {
  'AdicEthernetSpeed' => {
    '1' => 'baseT10',
    '2' => 'baseT100',
  },
  'AdicRasTicketState' => {
    '1' => 'new',
    '2' => 'open',
    '3' => 'suspended',
    '4' => 'closed',
    '5' => 'verified',
    '99' => 'all',
  },
  'AdicStatusGroupState' => {
    '1' => 'good',
    '2' => 'failed',
    '3' => 'degraded',
    '4' => 'warning',
    '5' => 'informational',
    '6' => 'unknown',
    '7' => 'invalid',
  },
  'AdicSegmentType' => {
    '1' => 'gripper',
    '2' => 'storage',
    '3' => 'ie',
    '4' => 'drive',
  },
  'MIBVERSION' => '1.93',
  'AdicRasTicketSeverity' => {
    '1' => 'high',
    '2' => 'medium',
    '3' => 'low',
  },
  'AdicStatusGroup' => {
    '1' => 'connectivity',
    '2' => 'control',
    '3' => 'cooling',
    '4' => 'drivesAndMedia',
    '5' => 'power',
    '6' => 'robotics',
    '99' => 'all',
  },
  'AdicFcPortType' => {
    '1' => 'auto',
    '2' => 'nPort',
    '3' => 'nlPort',
  },
  'Boolean' => {
    '1' => 'true',
    '2' => 'false',
  },
  'AdicInstallStatus' => {
    '1' => 'ok',
    '2' => 'inProgress',
    '3' => 'failed',
    '4' => 'updateAborted',
  },
  'AdicFcPortSpeed' => {
    '1' => 'auto',
    '1000' => 'megabits1000',
    '2000' => 'megabits2000',
  },
};


package Monitoring::GLPlugin::SNMP::MibsAndOids::QUANTUMSMALLTAPELIBRARYMIB;

$Monitoring::GLPlugin::SNMP::MibsAndOids::origin->{'QUANTUM-SMALL-TAPE-LIBRARY-MIB'} = {
  url => '',
  name => 'QUANTUM-SMALL-TAPE-LIBRARY-MIB',
};

$Monitoring::GLPlugin::SNMP::MibsAndOids::mib_ids->{'QUANTUM-SMALL-TAPE-LIBRARY-MIB'} = 
  '1.3.6.1.4.1.3697';

$Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{'QUANTUM-SMALL-TAPE-LIBRARY-MIB'} = {
  'smallTapeLibraryMIB' => '1.3.6.1.4.1.3697.1.10.10',
  'smallTapeLibrarySystem' => '1.3.6.1.4.1.3697.1.10.10.1',
  'libraryIpAddress' => '1.3.6.1.4.1.3697.1.10.10.1.1',
  'librarySNMPAgentDescription' => '1.3.6.1.4.1.3697.1.10.10.1.2',
  'libraryName' => '1.3.6.1.4.1.3697.1.10.10.1.3',
  'libraryVendor' => '1.3.6.1.4.1.3697.1.10.10.1.4',
  'librarySerialNumber' => '1.3.6.1.4.1.3697.1.10.10.1.5',
  'libraryDescription' => '1.3.6.1.4.1.3697.1.10.10.1.6',
  'libraryModel' => '1.3.6.1.4.1.3697.1.10.10.1.7',
  'libraryGlobalStatus' => '1.3.6.1.4.1.3697.1.10.10.1.8',
  'libraryGlobalStatusDefinition' => 'QUANTUM-SMALL-TAPE-LIBRARY-MIB::RASSubSystemStatus',
  'libraryURL' => '1.3.6.1.4.1.3697.1.10.10.1.9',
  'libraryProductName' => '1.3.6.1.4.1.3697.1.10.10.1.10',
  'libraryFirmwareVersion' => '1.3.6.1.4.1.3697.1.10.10.1.11',
  'physicalLibraryState' => '1.3.6.1.4.1.3697.1.10.10.1.15.1',
  'physicalLibraryStateDefinition' => 'QUANTUM-SMALL-TAPE-LIBRARY-MIB::LibraryReadyState',
  'aggregatedMainDoorStatus' => '1.3.6.1.4.1.3697.1.10.10.1.15.2',
  'aggregatedMainDoorStatusDefinition' => 'QUANTUM-SMALL-TAPE-LIBRARY-MIB::LibraryDoorStatus',
  'aggregatedIEDoorStatus' => '1.3.6.1.4.1.3697.1.10.10.1.15.3',
  'aggregatedIEDoorStatusDefinition' => 'QUANTUM-SMALL-TAPE-LIBRARY-MIB::IEDoorStatus',
  'libraryInterfaces' => '1.3.6.1.4.1.3697.1.10.10.1.15.4',
  'libraryControl' => '1.3.6.1.4.1.3697.1.10.10.1.15.4.1',
  'libraryCartridgeSlots' => '1.3.6.1.4.1.3697.1.10.10.1.15.5',
  'numStorageSlots' => '1.3.6.1.4.1.3697.1.10.10.1.15.5.1',
  'numCleanSlots' => '1.3.6.1.4.1.3697.1.10.10.1.15.5.2',
  'numIESlots' => '1.3.6.1.4.1.3697.1.10.10.1.15.5.3',
  'physicalDrive' => '1.3.6.1.4.1.3697.1.10.10.1.15.6',
  'numPhDrives' => '1.3.6.1.4.1.3697.1.10.10.1.15.6.1',
  'overallPhDriveOnlineStatus' => '1.3.6.1.4.1.3697.1.10.10.1.15.6.2',
  'overallPhDriveOnlineStatusDefinition' => 'QUANTUM-SMALL-TAPE-LIBRARY-MIB::OnlineState',
  'overallPhDriveReadinessStatus' => '1.3.6.1.4.1.3697.1.10.10.1.15.6.3',
  'overallPhDriveReadinessStatusDefinition' => 'QUANTUM-SMALL-TAPE-LIBRARY-MIB::DriveReadyState',
  'physicalDriveTable' => '1.3.6.1.4.1.3697.1.10.10.1.15.6.4',
  'physicalDriveEntry' => '1.3.6.1.4.1.3697.1.10.10.1.15.6.4.1',
  'phDriveIndex' => '1.3.6.1.4.1.3697.1.10.10.1.15.6.4.1.1',
  'phDriveLocation' => '1.3.6.1.4.1.3697.1.10.10.1.15.6.4.1.2',
  'phDriveDeviceId' => '1.3.6.1.4.1.3697.1.10.10.1.15.6.4.1.3',
  'phDriveVendor' => '1.3.6.1.4.1.3697.1.10.10.1.15.6.4.1.4',
  'phDriveType' => '1.3.6.1.4.1.3697.1.10.10.1.15.6.4.1.5',
  'phDriveInterfaceType' => '1.3.6.1.4.1.3697.1.10.10.1.15.6.4.1.6',
  'phDriveInterfaceTypeDefinition' => 'QUANTUM-SMALL-TAPE-LIBRARY-MIB::InterfaceType',
  'phDriveAddress' => '1.3.6.1.4.1.3697.1.10.10.1.15.6.4.1.7',
  'phDrivePhysicalSerialNumber' => '1.3.6.1.4.1.3697.1.10.10.1.15.6.4.1.8',
  'phDriveLogicalSerialNumber' => '1.3.6.1.4.1.3697.1.10.10.1.15.6.4.1.9',
  'phDriveFirmwareVersion' => '1.3.6.1.4.1.3697.1.10.10.1.15.6.4.1.10',
  'phDriveOnlineState' => '1.3.6.1.4.1.3697.1.10.10.1.15.6.4.1.11',
  'phDriveOnlineStateDefinition' => 'QUANTUM-SMALL-TAPE-LIBRARY-MIB::OnlineState',
  'phDriveReadinessState' => '1.3.6.1.4.1.3697.1.10.10.1.15.6.4.1.12',
  'phDriveReadinessStateDefinition' => 'QUANTUM-SMALL-TAPE-LIBRARY-MIB::DriveReadyState',
  'phDriveRasStatus' => '1.3.6.1.4.1.3697.1.10.10.1.15.6.4.1.13',
  'phDriveRasStatusDefinition' => 'QUANTUM-SMALL-TAPE-LIBRARY-MIB::RASSubSystemStatus',
  'phDriveLoads' => '1.3.6.1.4.1.3697.1.10.10.1.15.6.4.1.14',
  'phDriveCleaningStatus' => '1.3.6.1.4.1.3697.1.10.10.1.15.6.4.1.15',
  'phDriveCleaningStatusDefinition' => 'QUANTUM-SMALL-TAPE-LIBRARY-MIB::CleaningStatus',
  'phDriveLogicalLibraryName' => '1.3.6.1.4.1.3697.1.10.10.1.15.6.4.1.16',
  'phDriveControlPathDrive' => '1.3.6.1.4.1.3697.1.10.10.1.15.6.4.1.17',
  'rasSubSystem' => '1.3.6.1.4.1.3697.1.10.10.1.15.10',
  'powerStatus' => '1.3.6.1.4.1.3697.1.10.10.1.15.10.1',
  'powerStatusDefinition' => 'QUANTUM-SMALL-TAPE-LIBRARY-MIB::RASSubSystemStatus',
  'coolingStatus' => '1.3.6.1.4.1.3697.1.10.10.1.15.10.2',
  'coolingStatusDefinition' => 'QUANTUM-SMALL-TAPE-LIBRARY-MIB::RASSubSystemStatus',
  'controlStatus' => '1.3.6.1.4.1.3697.1.10.10.1.15.10.3',
  'controlStatusDefinition' => 'QUANTUM-SMALL-TAPE-LIBRARY-MIB::RASSubSystemStatus',
  'connectivityStatus' => '1.3.6.1.4.1.3697.1.10.10.1.15.10.4',
  'connectivityStatusDefinition' => 'QUANTUM-SMALL-TAPE-LIBRARY-MIB::RASSubSystemStatus',
  'roboticsStatus' => '1.3.6.1.4.1.3697.1.10.10.1.15.10.5',
  'roboticsStatusDefinition' => 'QUANTUM-SMALL-TAPE-LIBRARY-MIB::RASSubSystemStatus',
  'mediaStatus' => '1.3.6.1.4.1.3697.1.10.10.1.15.10.6',
  'mediaStatusDefinition' => 'QUANTUM-SMALL-TAPE-LIBRARY-MIB::RASSubSystemStatus',
  'driveStatus' => '1.3.6.1.4.1.3697.1.10.10.1.15.10.7',
  'driveStatusDefinition' => 'QUANTUM-SMALL-TAPE-LIBRARY-MIB::RASSubSystemStatus',
  'operatorActionRequest' => '1.3.6.1.4.1.3697.1.10.10.1.15.10.8',
  'operatorActionRequestDefinition' => 'QUANTUM-SMALL-TAPE-LIBRARY-MIB::NoYes',
  'logicalLibrary' => '1.3.6.1.4.1.3697.1.10.10.1.16',
  'numLogicalLibraries' => '1.3.6.1.4.1.3697.1.10.10.1.16.1',
  'logicalLibraryTable' => '1.3.6.1.4.1.3697.1.10.10.1.16.2',
  'logicalLibraryEntry' => '1.3.6.1.4.1.3697.1.10.10.1.16.2.1',
  'logicalLibraryIndex' => '1.3.6.1.4.1.3697.1.10.10.1.16.2.1.1',
  'logicalLibraryName' => '1.3.6.1.4.1.3697.1.10.10.1.16.2.1.2',
  'logicalLibrarySerialNumber' => '1.3.6.1.4.1.3697.1.10.10.1.16.2.1.3',
  'logicalLibraryModel' => '1.3.6.1.4.1.3697.1.10.10.1.16.2.1.4',
  'logicalLibraryInterface' => '1.3.6.1.4.1.3697.1.10.10.1.16.2.1.5',
  'logicalLibraryInterfaceDefinition' => 'QUANTUM-SMALL-TAPE-LIBRARY-MIB::InterfaceMethod',
  'logicalLibraryMediaDomain' => '1.3.6.1.4.1.3697.1.10.10.1.16.2.1.6',
  'logicalLibrarySupportedMediaTypes' => '1.3.6.1.4.1.3697.1.10.10.1.16.2.1.7',
  'logicalLibraryOnlineState' => '1.3.6.1.4.1.3697.1.10.10.1.16.2.1.8',
  'logicalLibraryOnlineStateDefinition' => 'QUANTUM-SMALL-TAPE-LIBRARY-MIB::OnlineState',
  'logicalLibraryReadyState' => '1.3.6.1.4.1.3697.1.10.10.1.16.2.1.9',
  'logicalLibraryReadyStateDefinition' => 'QUANTUM-SMALL-TAPE-LIBRARY-MIB::LibraryReadyState',
  'logicalLibraryAutoClean' => '1.3.6.1.4.1.3697.1.10.10.1.16.2.1.10',
  'logicalLibraryAutoCleanDefinition' => 'QUANTUM-SMALL-TAPE-LIBRARY-MIB::OnOff',
  'logicalLibraryNumSlots' => '1.3.6.1.4.1.3697.1.10.10.1.16.2.1.11',
  'logicalLibraryNumIE' => '1.3.6.1.4.1.3697.1.10.10.1.16.2.1.12',
  'logicalLibraryNumTapeDrives' => '1.3.6.1.4.1.3697.1.10.10.1.16.2.1.13',
  'logicalLibraryStorageElemAddr' => '1.3.6.1.4.1.3697.1.10.10.1.16.2.1.14',
  'logicalLibraryIEElemAddr' => '1.3.6.1.4.1.3697.1.10.10.1.16.2.1.15',
  'logicalLibraryTapeDriveElemAddr' => '1.3.6.1.4.1.3697.1.10.10.1.16.2.1.16',
  'logicalLibraryChangerDeviceAddr' => '1.3.6.1.4.1.3697.1.10.10.1.16.2.1.17',
};

$Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{'QUANTUM-SMALL-TAPE-LIBRARY-MIB'} = {
  'IEDoorStatus' => {
    '1' => 'open',
    '2' => 'closedAndLocked',
    '3' => 'closedAndUnLocked',
  },
  'LibraryReadyState' => {
    '1' => 'ready',
    '2' => 'notReady',
    '3' => 'becomingReady',
  },
  'InterfaceType' => {
    '1' => 'scsi',
    '2' => 'fibreChannel',
    '3' => 'sas',
    '4' => 'iscsi',
  },
  'InterfaceMethod' => {
    '1' => 'viaControlPathDrive',
    '2' => 'viaConnectionBlade',
    '3' => 'viaDriveAndBlade',
  },
  'NoYes' => {
    '0' => 'no',
    '1' => 'yes',
  },
  'CleaningStatus' => {
    '1' => 'recommended',
    '2' => 'notNeeded',
    '3' => 'required',
  },
  'DriveReadyState' => {
    '1' => 'ready',
    '2' => 'notReady',
    '3' => 'notInstalled',
  },
  'OnlineState' => {
    '1' => 'online',
    '2' => 'onlinePending',
    '3' => 'offline',
    '4' => 'offlinePending',
    '5' => 'shutdownPending',
  },
  'RASSubSystemStatus' => {
    '1' => 'good',
    '2' => 'failed',
    '3' => 'degraded',
    '4' => 'warning',
    '5' => 'informational',
    '6' => 'unknown',
    '7' => 'invalid',
  },
  'OnOff' => {
    '0' => 'off',
    '1' => 'on',
  },
  'LibraryDoorStatus' => {
    '1' => 'open',
    '2' => 'closed',
    '3' => 'unknown',
  },
};



package Monitoring::GLPlugin::SNMP::MibsAndOids::SEMIMIB;

$Monitoring::GLPlugin::SNMP::MibsAndOids::origin->{'SEMI-MIB'} = {
  url => '',
  name => 'SEMI-MIB',
};

$Monitoring::GLPlugin::SNMP::MibsAndOids::mib_ids->{'SEMI-MIB'} = 
  '1.3.6.1.4.1.11.10.2.1.3.25';

$Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{'SEMI-MIB'} = {
  'hpWebMgmt' => '1.3.6.1.4.1.11.2.36',
  'hpHttpMgMod' => '1.3.6.1.4.1.11.2.36.1',
  'hpHttpMgTraps' => '1.3.6.1.4.1.11.2.36.1.0',
  'hpHttpMgHealthTrap' => '1.3.6.1.4.1.11.2.36.1.0.1',
  'hpHttpMgShutdown' => '1.3.6.1.4.1.11.2.36.1.0.2',
  'hpHttpMgUnknownHealthTrap' => '1.3.6.1.4.1.11.2.36.1.0.3',
  'hpHttpMgOKHealthTrap' => '1.3.6.1.4.1.11.2.36.1.0.4',
  'hpHttpMgWarningHealthTrap' => '1.3.6.1.4.1.11.2.36.1.0.5',
  'hpHttpMgCriticalHealthTrap' => '1.3.6.1.4.1.11.2.36.1.0.6',
  'hpHttpMgNonRecoverableHealthTrap' => '1.3.6.1.4.1.11.2.36.1.0.7',
  'hpHttpMgDeviceAddedTrap' => '1.3.6.1.4.1.11.2.36.1.0.8',
  'hpHttpMgDeviceRemovedTrap' => '1.3.6.1.4.1.11.2.36.1.0.9',
  'hpHttpMgDeviceSpecificEventCode' => '1.3.6.1.4.1.11.2.36.1.0.10',
  'hpHttpMgDeviceSpecificFRU' => '1.3.6.1.4.1.11.2.36.1.0.11',
  'hpHttpMgObjects' => '1.3.6.1.4.1.11.2.36.1.1',
  'hpHttpMgDefaults' => '1.3.6.1.4.1.11.2.36.1.1.1',
  'hpHttpMgDefaultURL' => '1.3.6.1.4.1.11.2.36.1.1.1.1',
  'hpHttpMgNetCitizen' => '1.3.6.1.4.1.11.2.36.1.1.2',
  'hpHttpMgMgmtSrvrURL' => '1.3.6.1.4.1.11.2.36.1.1.2.1',
  'hpHttpMgID' => '1.3.6.1.4.1.11.2.36.1.1.2.2',
  'hpHttpMgHealth' => '1.3.6.1.4.1.11.2.36.1.1.2.3',
  'hpHttpMgHealthDefinition' => 'SEMI-MIB::hpHttpMgHealth',
  'hpHttpMgManufacturer' => '1.3.6.1.4.1.11.2.36.1.1.2.4',
  'hpHttpMgProduct' => '1.3.6.1.4.1.11.2.36.1.1.2.5',
  'hpHttpMgVersion' => '1.3.6.1.4.1.11.2.36.1.1.2.6',
  'hpHttpMgHWVersion' => '1.3.6.1.4.1.11.2.36.1.1.2.7',
  'hpHttpMgROMVersion' => '1.3.6.1.4.1.11.2.36.1.1.2.8',
  'hpHttpMgSerialNumber' => '1.3.6.1.4.1.11.2.36.1.1.2.9',
  'hpHttpMgAssetNumber' => '1.3.6.1.4.1.11.2.36.1.1.2.10',
  'hpHttpMgPhone' => '1.3.6.1.4.1.11.2.36.1.1.2.11',
  'hpHttpMgEntityNetInfo' => '1.3.6.1.4.1.11.2.36.1.1.3',
  'hpHttpMgEntityNetInfoTable' => '1.3.6.1.4.1.11.2.36.1.1.3.1',
  'hpHttpMgEntityNetInfoEntry' => '1.3.6.1.4.1.11.2.36.1.1.3.1.1',
  'hpHttpMgEntityNetInfoIndex' => '1.3.6.1.4.1.11.2.36.1.1.3.1.1.1',
  'hpHttpMgEntityNetInfoSysObjID' => '1.3.6.1.4.1.11.2.36.1.1.3.1.1.2',
  'hpHttpMgEntityNetInfoRelationshipType' => '1.3.6.1.4.1.11.2.36.1.1.3.1.1.3',
  'hpHttpMgEntityNetInfoUniqueID' => '1.3.6.1.4.1.11.2.36.1.1.3.1.1.4',
  'hpHttpMgEntityNetInfoURL' => '1.3.6.1.4.1.11.2.36.1.1.3.1.1.5',
  'hpHttpMgEntityNetInfoURLLabel' => '1.3.6.1.4.1.11.2.36.1.1.3.1.1.6',
  'hpHttpMgEntityNetInfoIPAddress' => '1.3.6.1.4.1.11.2.36.1.1.3.1.1.7',
  'hpHttpMgCluster' => '1.3.6.1.4.1.11.2.36.1.1.4',
  'hpHttpMgClusterName' => '1.3.6.1.4.1.11.2.36.1.1.4.1',
  'hpHttpMgDeviceInfo' => '1.3.6.1.4.1.11.2.36.1.1.5',
  'hpHttpMgDeviceTable' => '1.3.6.1.4.1.11.2.36.1.1.5.1',
  'hpHttpMgDeviceEntry' => '1.3.6.1.4.1.11.2.36.1.1.5.1.1',
  'hpHttpMgDeviceIndex' => '1.3.6.1.4.1.11.2.36.1.1.5.1.1.1',
  'hpHttpMgDeviceGlobalUniqueID' => '1.3.6.1.4.1.11.2.36.1.1.5.1.1.2',
  'hpHttpMgDeviceHealth' => '1.3.6.1.4.1.11.2.36.1.1.5.1.1.3',
  'hpHttpMgDeviceHealthDefinition' => 'SEMI-MIB::hpHttpMgDeviceHealth',
  'hpHttpMgDeviceSysObjID' => '1.3.6.1.4.1.11.2.36.1.1.5.1.1.4',
  'hpHttpMgDeviceManagementURL' => '1.3.6.1.4.1.11.2.36.1.1.5.1.1.5',
  'hpHttpMgDeviceManagementURLLabel' => '1.3.6.1.4.1.11.2.36.1.1.5.1.1.6',
  'hpHttpMgDeviceManufacturer' => '1.3.6.1.4.1.11.2.36.1.1.5.1.1.7',
  'hpHttpMgDeviceProductName' => '1.3.6.1.4.1.11.2.36.1.1.5.1.1.8',
  'hpHttpMgDeviceProductCaption' => '1.3.6.1.4.1.11.2.36.1.1.5.1.1.9',
  'hpHttpMgDeviceSerialNumber' => '1.3.6.1.4.1.11.2.36.1.1.5.1.1.10',
  'hpHttpMgDeviceVersion' => '1.3.6.1.4.1.11.2.36.1.1.5.1.1.11',
  'hpHttpMgDeviceHWVersion' => '1.3.6.1.4.1.11.2.36.1.1.5.1.1.12',
  'hpHttpMgDeviceROMVersion' => '1.3.6.1.4.1.11.2.36.1.1.5.1.1.13',
  'hpHttpMgDeviceAssetNumber' => '1.3.6.1.4.1.11.2.36.1.1.5.1.1.14',
  'hpHttpMgDeviceContactPerson' => '1.3.6.1.4.1.11.2.36.1.1.5.1.1.15',
  'hpHttpMgDeviceContactPhone' => '1.3.6.1.4.1.11.2.36.1.1.5.1.1.16',
  'hpHttpMgDeviceContactEmail' => '1.3.6.1.4.1.11.2.36.1.1.5.1.1.17',
  'hpHttpMgDeviceContactPagerNumber' => '1.3.6.1.4.1.11.2.36.1.1.5.1.1.18',
  'hpHttpMgDeviceLocation' => '1.3.6.1.4.1.11.2.36.1.1.5.1.1.19',
  'hpHttpMgDeviceRackId' => '1.3.6.1.4.1.11.2.36.1.1.5.1.1.20',
  'hpHttpMgDeviceRackPosition' => '1.3.6.1.4.1.11.2.36.1.1.5.1.1.21',
  'hpHttpMgDeviceRelationshipType' => '1.3.6.1.4.1.11.2.36.1.1.5.1.1.22',
  'hpHttpMgDeviceSWID' => '1.3.6.1.4.1.11.2.36.1.1.5.1.1.23',
};

$Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{'SEMI-MIB'} = {
  'hpHttpMgDeviceHealth' => {
    '1' => 'unknown',
    '2' => 'unused',
    '3' => 'ok',
    '4' => 'warning',
    '5' => 'critical',
    '6' => 'nonrecoverable',
  },
  'hpHttpMgHealth' => {
    '1' => 'unknown',
    '2' => 'information',
    '3' => 'ok',
    '4' => 'warning',
    '5' => 'critical',
    '6' => 'nonrecoverable',
  },
};



package Monitoring::GLPlugin::SNMP::MibsAndOids::SLHWLIBT950MIB;

$Monitoring::GLPlugin::SNMP::MibsAndOids::origin->{'SL-HW-LIB-T950-MIB'} = {
  url => '',
  name => 'SL-HW-LIB-T950-MIB',
};

$Monitoring::GLPlugin::SNMP::MibsAndOids::mib_ids->{'SL-HW-LIB-T950-MIB'} = 
  '1.3.6.1.4.1.3478.1.1.3.1.1';

$Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{'SL-HW-LIB-T950-MIB'} = {
  'slT950MIB' => '1.3.6.1.4.1.3478.1.1.3.1.1',
  'slT950Confs' => '1.3.6.1.4.1.3478.1.1.3.1.1.1',
  'slT950Groups' => '1.3.6.1.4.1.3478.1.1.3.1.1.1.1',
  'slT950Compl' => '1.3.6.1.4.1.3478.1.1.3.1.1.1.2',
  'slT950Objs' => '1.3.6.1.4.1.3478.1.1.3.1.1.2',
  'slT950LibraryObjs' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1',
  'slT950GeneralObjs' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1.1',
  'slT950GeneralStatusObjs' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1.1.1',
  'slT950GeneralStatusPowerStatus' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1.1.1.1',
  'slT950GeneralStatusPowerStatusDefinition' => 'SL-HW-LIB-T950-MIB::SLComponentStatus',
  'slT950GeneralStatusFansStatus' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1.1.1.2',
  'slT950GeneralStatusFansStatusDefinition' => {
    '1' => 'ok',
    '2' => 'warning',
    '3' => 'failure',
  },
  'slT950GeneralStatusTap1Status' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1.1.1.3',
  'slT950GeneralStatusTap1StatusDefinition' => {
    '1' => 'ok',
    '2' => 'warning',
    '3' => 'failure',
  },
  'slT950GeneralStatusTap2Status' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1.1.1.4',
  'slT950GeneralStatusTap2StatusDefinition' => {
    '1' => 'ok',
    '2' => 'warning',
    '3' => 'failure',
  },
  'slT950GeneralStatusPartitionCount' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1.1.1.5',
  'slT950GeneralStatusPartitionTable' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1.1.1.6',
  'slT950GeneralStatusPartitionEntry' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1.1.1.6.1',
  'slT950GeneralStatusPartitionIndex' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1.1.1.6.1.1',
  'slT950GeneralStatusPartitionName' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1.1.1.6.1.2',
  'slT950GeneralStatusPartitionTotalAvailableDrives' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1.1.1.6.1.3',
  'slT950GeneralStatusPartitionFullDrives' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1.1.1.6.1.4',
  'slT950GeneralStatusPartitionTotalAvailableStorageSlots' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1.1.1.6.1.5',
  'slT950GeneralStatusPartitionFullStorageSlots' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1.1.1.6.1.6',
  'slT950GeneralStatusPartitionTotalAvailableEntryExitSlots' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1.1.1.6.1.7',
  'slT950GeneralStatusPartitionFullEntryExitSlots' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1.1.1.6.1.8',
  'slT950InventoryObjs' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1.1.2',
  'slT950ConfigurationObjs' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1.2',
  'slT950MaintenancelObjs' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1.3',
  'slT950SecurityObjs' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1.4',
  'slT950MessageObjs' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1.5',
  'slT950MessageCount' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1.5.1',
  'slT950MessageTable' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1.5.2',
  'slT950MessageEntry' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1.5.2.1',
  'slT950MessageIndex' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1.5.2.1.1',
  'slT950MessageNumber' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1.5.2.1.2',
  'slT950MessageSeverity' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1.5.2.1.3',
  'slT950MessageSeverityDefinition' => {
    '1' => 'info',
    '2' => 'warning',
    '3' => 'error',
    '4' => 'fatal',
  },
  'slT950MessageText' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1.5.2.1.4',
  'slT950MessageRemedyText' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1.5.2.1.5',
  'slT950MessageTime' => '1.3.6.1.4.1.3478.1.1.3.1.1.2.1.5.2.1.6',
  'slT950Events' => '1.3.6.1.4.1.3478.1.1.3.1.1.3',
  'slT950EventsV2' => '1.3.6.1.4.1.3478.1.1.3.1.1.3.0',
  'slT950MibModule' => '1.3.6.1.4.1.3478.3.1.4',
};

$Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{'SL-HW-LIB-T950-MIB'} = {
  'SLComponentStatus' => {
    '1' => 'ok',
    '2' => 'failure',
  },
};



package Monitoring::GLPlugin::SNMP::MibsAndOids::SPECTRALOGICGLOBALREG;

$Monitoring::GLPlugin::SNMP::MibsAndOids::origin->{'SPECTRALOGIC-GLOBAL-REG'} = {
  url => '',
  name => 'SPECTRALOGIC-GLOBAL-REG',
};

$Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{'SPECTRALOGIC-GLOBAL-REG'} = {
  'spectralogic' => '1.3.6.1.4.1.3478',
  'slHardware' => '1.3.6.1.4.1.3478.1',
  'slLibraries' => '1.3.6.1.4.1.3478.1.1',
  'slTSeries' => '1.3.6.1.4.1.3478.1.1.3',
  'slT950' => '1.3.6.1.4.1.3478.1.1.3.1',
};




package Monitoring::GLPlugin::SNMP::MibsAndOids::SPECTRALOGICGLOBALREGSLHARDWARESLLIBRARIESSLTSERIES;

$Monitoring::GLPlugin::SNMP::MibsAndOids::origin->{'SPECTRALOGIC-GLOBAL-REG-SLHARDWARE-SLLIBRARIES-SLTSERIES'} = {
  url => '',
  name => 'SPECTRALOGIC-GLOBAL-REG-SLHARDWARE-SLLIBRARIES-SLTSERIES',
};

$Monitoring::GLPlugin::SNMP::MibsAndOids::mib_ids->{'SPECTRALOGIC-GLOBAL-REG-SLHARDWARE-SLLIBRARIES-SLTSERIES'} =
  '1.3.6.1.4.1.3478.1.1.3';


package Monitoring::GLPlugin::SNMP::MibsAndOids::UCDSNMPMIB;

$Monitoring::GLPlugin::SNMP::MibsAndOids::origin->{'UCD-SNMP-MIB'} = {
  url => 'http://www.net-snmp.org/docs/mibs/UCD-SNMP-MIB.txt',
  name => 'UCD-SNMP-MIB',
};

$Monitoring::GLPlugin::SNMP::MibsAndOids::mib_ids->{'UCD-SNMP-MIB'} =
    '1.3.6.1.4.1.2021';

$Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{'UCD-SNMP-MIB'} = {
  ucdavis => '1.3.6.1.4.1.2021',
  prTable => '1.3.6.1.4.1.2021.2',
  prEntry => '1.3.6.1.4.1.2021.2.1',
  prIndex => '1.3.6.1.4.1.2021.2.1.1',
  prNames => '1.3.6.1.4.1.2021.2.1.2',
  prMin => '1.3.6.1.4.1.2021.2.1.3',
  prMax => '1.3.6.1.4.1.2021.2.1.4',
  prCount => '1.3.6.1.4.1.2021.2.1.5',
  prErrorFlag => '1.3.6.1.4.1.2021.2.1.100',
  prErrorFlagDefinition => 'UCD-SNMP-MIB::UCDErrorFlag',
  prErrMessage => '1.3.6.1.4.1.2021.2.1.101',
  prErrFix => '1.3.6.1.4.1.2021.2.1.102',
  prErrFixDefinition => 'UCD-SNMP-MIB::UCDErrorFix',
  prErrFixCmd => '1.3.6.1.4.1.2021.2.1.103',
  memory => '1.3.6.1.4.1.2021.4',
  memIndex => '1.3.6.1.4.1.2021.4.1',
  memErrorName => '1.3.6.1.4.1.2021.4.2',
  memTotalSwap => '1.3.6.1.4.1.2021.4.3',
  memAvailSwap => '1.3.6.1.4.1.2021.4.4',
  memTotalReal => '1.3.6.1.4.1.2021.4.5',
  memAvailReal => '1.3.6.1.4.1.2021.4.6',
  memTotalSwapTXT => '1.3.6.1.4.1.2021.4.7',
  memAvailSwapTXT => '1.3.6.1.4.1.2021.4.8',
  memTotalRealTXT => '1.3.6.1.4.1.2021.4.9',
  memAvailRealTXT => '1.3.6.1.4.1.2021.4.10',
  memTotalFree => '1.3.6.1.4.1.2021.4.11',
  memMinimumSwap => '1.3.6.1.4.1.2021.4.12',
  memShared => '1.3.6.1.4.1.2021.4.13',
  memBuffer => '1.3.6.1.4.1.2021.4.14',
  memCached => '1.3.6.1.4.1.2021.4.15',
  memUsedSwapTXT => '1.3.6.1.4.1.2021.4.16',
  memUsedRealTXT => '1.3.6.1.4.1.2021.4.17',
  memSwapError => '1.3.6.1.4.1.2021.4.100',
  memSwapErrorDefinition => 'UCD-SNMP-MIB::UCDErrorFlag',
  memSwapErrorMsg => '1.3.6.1.4.1.2021.4.101',
  extTable => '1.3.6.1.4.1.2021.8',
  extEntry => '1.3.6.1.4.1.2021.8.1',
  extIndex => '1.3.6.1.4.1.2021.8.1.1',
  extNames => '1.3.6.1.4.1.2021.8.1.2',
  extCommand => '1.3.6.1.4.1.2021.8.1.3',
  extResult => '1.3.6.1.4.1.2021.8.1.100',
  extOutput => '1.3.6.1.4.1.2021.8.1.101',
  extErrFix => '1.3.6.1.4.1.2021.8.1.102',
  extErrFixDefinition => 'UCD-SNMP-MIB::UCDErrorFix',
  extErrFixCmd => '1.3.6.1.4.1.2021.8.1.103',
  dskTable => '1.3.6.1.4.1.2021.9',
  dskEntry => '1.3.6.1.4.1.2021.9.1',
  dskIndex => '1.3.6.1.4.1.2021.9.1.1',
  dskPath => '1.3.6.1.4.1.2021.9.1.2',
  dskDevice => '1.3.6.1.4.1.2021.9.1.3',
  dskMinimum => '1.3.6.1.4.1.2021.9.1.4',
  dskMinPercent => '1.3.6.1.4.1.2021.9.1.5',
  dskTotal => '1.3.6.1.4.1.2021.9.1.6',
  dskAvail => '1.3.6.1.4.1.2021.9.1.7',
  dskUsed => '1.3.6.1.4.1.2021.9.1.8',
  dskPercent => '1.3.6.1.4.1.2021.9.1.9',
  dskPercentNode => '1.3.6.1.4.1.2021.9.1.10',
  dskTotalLow => '1.3.6.1.4.1.2021.9.1.11',
  dskTotalHigh => '1.3.6.1.4.1.2021.9.1.12',
  dskAvailLow => '1.3.6.1.4.1.2021.9.1.13',
  dskAvailHigh => '1.3.6.1.4.1.2021.9.1.14',
  dskUsedLow => '1.3.6.1.4.1.2021.9.1.15',
  dskUsedHigh => '1.3.6.1.4.1.2021.9.1.16',
  dskErrorFlag => '1.3.6.1.4.1.2021.9.1.100',
  dskErrorFlagDefinition => 'UCD-SNMP-MIB::UCDErrorFlag',
  dskErrorMsg => '1.3.6.1.4.1.2021.9.1.101',
  laTable => '1.3.6.1.4.1.2021.10',
  laEntry => '1.3.6.1.4.1.2021.10.1',
  laIndex => '1.3.6.1.4.1.2021.10.1.1',
  laNames => '1.3.6.1.4.1.2021.10.1.2',
  laLoad => '1.3.6.1.4.1.2021.10.1.3',
  laConfig => '1.3.6.1.4.1.2021.10.1.4',
  laLoadInt => '1.3.6.1.4.1.2021.10.1.5',
  laLoadFloat => '1.3.6.1.4.1.2021.10.1.6',
  laErrorFlag => '1.3.6.1.4.1.2021.10.1.100',
  laErrorFlagDefinition => 'UCD-SNMP-MIB::UCDErrorFlag',
  laErrMessage => '1.3.6.1.4.1.2021.10.1.101',
  systemStats => '1.3.6.1.4.1.2021.11',
  ssIndex => '1.3.6.1.4.1.2021.11.1',
  ssErrorName => '1.3.6.1.4.1.2021.11.2',
  ssSwapIn => '1.3.6.1.4.1.2021.11.3',
  ssSwapOut => '1.3.6.1.4.1.2021.11.4',
  ssIOSent => '1.3.6.1.4.1.2021.11.5',
  ssIOReceive => '1.3.6.1.4.1.2021.11.6',
  ssSysInterrupts => '1.3.6.1.4.1.2021.11.7',
  ssSysContext => '1.3.6.1.4.1.2021.11.8',
  ssCpuUser => '1.3.6.1.4.1.2021.11.9',
  ssCpuSystem => '1.3.6.1.4.1.2021.11.10',
  ssCpuIdle => '1.3.6.1.4.1.2021.11.11',
  ssCpuRawUser => '1.3.6.1.4.1.2021.11.50',
  ssCpuRawNice => '1.3.6.1.4.1.2021.11.51',
  ssCpuRawSystem => '1.3.6.1.4.1.2021.11.52',
  ssCpuRawIdle => '1.3.6.1.4.1.2021.11.53',
  ssCpuRawWait => '1.3.6.1.4.1.2021.11.54',
  ssCpuRawKernel => '1.3.6.1.4.1.2021.11.55',
  ssCpuRawInterrupt => '1.3.6.1.4.1.2021.11.56',
  ssIORawSent => '1.3.6.1.4.1.2021.11.57',
  ssIORawReceived => '1.3.6.1.4.1.2021.11.58',
  ssRawInterrupts => '1.3.6.1.4.1.2021.11.59',
  ssRawContexts => '1.3.6.1.4.1.2021.11.60',
  ssCpuRawSoftIRQ => '1.3.6.1.4.1.2021.11.61',
  ssRawSwapIn => '1.3.6.1.4.1.2021.11.62',
  ssRawSwapOut => '1.3.6.1.4.1.2021.11.63',
  ssCpuRawSteal => '1.3.6.1.4.1.2021.11.64',
  ssCpuRawGuest => '1.3.6.1.4.1.2021.11.65',
  ssCpuRawGuestNice => '1.3.6.1.4.1.2021.11.66',
  ucdInternal => '1.3.6.1.4.1.2021.12',
  ucdExperimental => '1.3.6.1.4.1.2021.13',
  fileTable => '1.3.6.1.4.1.2021.15',
  fileEntry => '1.3.6.1.4.1.2021.15.1',
  fileIndex => '1.3.6.1.4.1.2021.15.1.1',
  fileName => '1.3.6.1.4.1.2021.15.1.2',
  fileSize => '1.3.6.1.4.1.2021.15.1.3',
  fileMax => '1.3.6.1.4.1.2021.15.1.4',
  fileErrorFlag => '1.3.6.1.4.1.2021.15.1.100',
  fileErrorFlagDefinition => 'UCD-SNMP-MIB::UCDErrorFlag',
  fileErrorMsg => '1.3.6.1.4.1.2021.15.1.101',
  logMatch => '1.3.6.1.4.1.2021.16',
  logMatchMaxEntries => '1.3.6.1.4.1.2021.16.1',
  logMatchTable => '1.3.6.1.4.1.2021.16.2',
  logMatchEntry => '1.3.6.1.4.1.2021.16.2.1',
  logMatchIndex => '1.3.6.1.4.1.2021.16.2.1.1',
  logMatchName => '1.3.6.1.4.1.2021.16.2.1.2',
  logMatchFilename => '1.3.6.1.4.1.2021.16.2.1.3',
  logMatchRegEx => '1.3.6.1.4.1.2021.16.2.1.4',
  logMatchGlobalCounter => '1.3.6.1.4.1.2021.16.2.1.5',
  logMatchGlobalCount => '1.3.6.1.4.1.2021.16.2.1.6',
  logMatchCurrentCounter => '1.3.6.1.4.1.2021.16.2.1.7',
  logMatchCurrentCount => '1.3.6.1.4.1.2021.16.2.1.8',
  logMatchCounter => '1.3.6.1.4.1.2021.16.2.1.9',
  logMatchCount => '1.3.6.1.4.1.2021.16.2.1.10',
  logMatchCycle => '1.3.6.1.4.1.2021.16.2.1.11',
  logMatchErrorFlag => '1.3.6.1.4.1.2021.16.2.1.100',
  logMatchErrorFlagDefinition => 'UCD-SNMP-MIB::UCDErrorFlag',
  logMatchRegExCompilation => '1.3.6.1.4.1.2021.16.2.1.101',
  version => '1.3.6.1.4.1.2021.100',
  versionIndex => '1.3.6.1.4.1.2021.100.1',
  versionTag => '1.3.6.1.4.1.2021.100.2',
  versionDate => '1.3.6.1.4.1.2021.100.3',
  versionCDate => '1.3.6.1.4.1.2021.100.4',
  versionIdent => '1.3.6.1.4.1.2021.100.5',
  versionConfigureOptions => '1.3.6.1.4.1.2021.100.6',
  versionClearCache => '1.3.6.1.4.1.2021.100.10',
  versionUpdateConfig => '1.3.6.1.4.1.2021.100.11',
  versionRestartAgent => '1.3.6.1.4.1.2021.100.12',
  versionSavePersistentData => '1.3.6.1.4.1.2021.100.13',
  versionDoDebugging => '1.3.6.1.4.1.2021.100.20',
  snmperrs => '1.3.6.1.4.1.2021.101',
  snmperrIndex => '1.3.6.1.4.1.2021.101.1',
  snmperrNames => '1.3.6.1.4.1.2021.101.2',
  snmperrErrorFlag => '1.3.6.1.4.1.2021.101.100',
  snmperrErrorFlagDefinition => 'UCD-SNMP-MIB::UCDErrorFlag',
  snmperrErrMessage => '1.3.6.1.4.1.2021.101.101',
  mrTable => '1.3.6.1.4.1.2021.102',
  mrEntry => '1.3.6.1.4.1.2021.102.1',
  mrIndex => '1.3.6.1.4.1.2021.102.1.1',
  mrModuleName => '1.3.6.1.4.1.2021.102.1.2',
  ucdSnmpAgent => '1.3.6.1.4.1.2021.250',
  hpux9 => '1.3.6.1.4.1.2021.250.1',
  sunos4 => '1.3.6.1.4.1.2021.250.2',
  solaris => '1.3.6.1.4.1.2021.250.3',
  osf => '1.3.6.1.4.1.2021.250.4',
  ultrix => '1.3.6.1.4.1.2021.250.5',
  hpux10 => '1.3.6.1.4.1.2021.250.6',
  netbsd1 => '1.3.6.1.4.1.2021.250.7',
  freebsd => '1.3.6.1.4.1.2021.250.8',
  irix => '1.3.6.1.4.1.2021.250.9',
  linux => '1.3.6.1.4.1.2021.250.10',
  bsdi => '1.3.6.1.4.1.2021.250.11',
  openbsd => '1.3.6.1.4.1.2021.250.12',
  win32 => '1.3.6.1.4.1.2021.250.13',
  hpux11 => '1.3.6.1.4.1.2021.250.14',
  aix => '1.3.6.1.4.1.2021.250.15',
  macosx => '1.3.6.1.4.1.2021.250.16',
  dragonfly => '1.3.6.1.4.1.2021.250.17',
  unknown => '1.3.6.1.4.1.2021.250.255',
  ucdTraps => '1.3.6.1.4.1.2021.251',
};

$Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{'UCD-SNMP-MIB'} = {
  UCDErrorFix => {
    '0' => 'noError',
    '1' => 'runFix',
  },
  UCDErrorFlag => {
    '0' => 'noError',
    '1' => 'error',
  },
};
package Classes::Quantum::I40I80::Components::EnvironmentalSubsystem;
our @ISA = qw(Monitoring::GLPlugin::SNMP::Item);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };

sub init {
  my $self = shift;
  $self->get_snmp_objects('QUANTUM-SMALL-TAPE-LIBRARY-MIB', (qw(powerStatus
      coolingStatus controlStatus connectivityStatus
      roboticsStatus mediaStatus driveStatus operatorActionRequest
      aggregatedMainDoorStatus aggregatedIEDoorStatus
      libraryControl numStorageSlots numCleanSlots numIESlots
      numLogicalLibraries
      librarySNMPAgentDescription libraryName libraryVendor
      librarySerialNumber libraryDescription libraryModel
      libraryGlobalStatus libraryURL)));
}

sub check {
  my $self = shift;
  $self->add_info('checking overall system');
  my $states = {
    OK => [],
    WARNING => [],
    CRITICAL => [],
    UNKNOWN => [],
  };
  foreach (qw(powerStatus coolingStatus controlStatus connectivityStatus
      roboticsStatus mediaStatus driveStatus)) {
    if ($self->{$_} eq 'degraded' or $self->{$_} eq 'warning') {
      $self->set_level(WARNING);
      push(@{$states->{WARNING}}, [$_, $self->{$_}]);
    } elsif ($self->{$_} eq 'unknown') {
      $self->set_level(UNKNOWN);
      push(@{$states->{UNKNOWN}}, [$_, $self->{$_}]);
    } elsif ($self->{$_} eq 'good' or $self->{$_} eq 'informational') {
      push(@{$states->{OK}}, [$_, $self->{$_}]);
    } else {
      $self->set_level(CRITICAL);
      push(@{$states->{CRITICAL}}, [$_, $self->{$_}]);
    }
  }
  if ($self->{operatorActionRequest} eq 'yes') {
    $self->set_level(CRITICAL);
    $self->add_message(CRITICAL, 'operator action requested');
  }
  if ($self->{aggregatedMainDoorStatus} eq 'open') {
    $self->set_level(CRITICAL);
    push(@{$states->{CRITICAL}}, ['aggregatedMainDoorStatus', $self->{aggregatedMainDoorStatus}]);
  } elsif ($self->{aggregatedMainDoorStatus} eq 'closedAndUnLocked') {
    $self->set_level(WARNING);
    push(@{$states->{WARNING}}, ['aggregatedMainDoorStatus', $self->{aggregatedMainDoorStatus}]);
  } elsif ($self->{aggregatedMainDoorStatus} eq 'unknown') {
    $self->set_level(UNKNOWN);
    push(@{$states->{UNKNOWN}}, ['aggregatedMainDoorStatus', $self->{aggregatedMainDoorStatus}]);
  }
  if ($self->{aggregatedIEDoorStatus} eq 'open') {
    $self->set_level(CRITICAL);
    push(@{$states->{CRITICAL}}, ['aggregatedIEDoorStatus', $self->{aggregatedIEDoorStatus}]);
  } elsif ($self->{aggregatedIEDoorStatus} eq 'closedAndUnLocked') {
    $self->set_level(WARNING);
    push(@{$states->{WARNING}}, ['aggregatedIEDoorStatus', $self->{aggregatedIEDoorStatus}]);
  }
  $self->add_info(sprintf 'overall states: %s', join(' ', map { $_->[0].'='.$_->[1] } map { my $x = $_->[0]; $x =~ s/Status//; [$x, $_->[1]] } (@{$states->{CRITICAL}}, @{$states->{WARNING}}, @{$states->{UNKNOWN}}, @{$states->{OK}})));
  if ($self->get_level()) {
    $self->add_message($self->get_level());
  }
}

package Classes::Quantum::I40I80::Components::LogicalLibrarySubsystem;
our @ISA = qw(Monitoring::GLPlugin::SNMP::Item);
use strict;

sub init {
  my $self = shift;
  $self->get_snmp_tables('QUANTUM-SMALL-TAPE-LIBRARY-MIB', [
      ['logical_libraries', 'logicalLibraryTable', 'Classes::Quantum::I40I80::Components::LogicalLibrary'],
  ]);
}

sub check {
  my $self = shift;
  $self->add_info('checking logical libraries');
  foreach (@{$self->{logical_libraries}}) {
    $_->check();
  }
}


package Classes::Quantum::I40I80::Components::LogicalLibrary;
our @ISA = qw(Monitoring::GLPlugin::SNMP::TableItem);
use strict;

sub check {
  my $self = shift;
  $self->{logicalLibraryIndex} ||= $self->{flat_indices};
  $self->add_info(sprintf 'logical lib %d states: online=%s readyness=%s',
      $self->{logicalLibraryIndex}, $self->{logicalLibraryOnlineState},
      $self->{logicalLibraryReadyState});
  if ($self->{logicalLibraryOnlineState} =~ /pending/i) {
    $self->set_level_warning();
  } elsif ($self->{logicalLibraryOnlineState} eq 'offline') {
    $self->set_level_critical();
  }
  if ($self->{logicalLibraryReadyState} eq 'becomingReady') {
    $self->set_level_warning();
  } elsif ($self->{logicalLibraryReadyState} eq 'notReady') {
    $self->set_level_critical();
  }
  if ($self->get_level()) {
    $self->add_message($self->get_level());
  }
}

package Classes::Quantum::I40I80::Components::DriveSubsystem;
our @ISA = qw(Monitoring::GLPlugin::SNMP::Item);
use strict;

sub init {
  my $self = shift;
  $self->get_snmp_tables('QUANTUM-SMALL-TAPE-LIBRARY-MIB', [
      ['phycsical_drives', 'physicalDriveTable', 'Classes::Quantum::I40I80::Components::PhysicalDrive'],
  ]);
  $self->get_snmp_objects('QUANTUM-SMALL-TAPE-LIBRARY-MIB', (qw(
      numPhDrives overallPhDriveOnlineStatus overallPhDriveReadinessStatus)));
}

sub check {
  my $self = shift;
  $self->add_info('checking physical drives');
  $self->add_info(sprintf 'overall drive status online=%s readyness=%s',
      $self->{overallPhDriveOnlineStatus},
      $self->{overallPhDriveReadinessStatus});
  if ($self->{overallPhDriveOnlineStatus} =~ /pending/i) {
    $self->add_warning();
  } elsif ($self->{overallPhDriveOnlineStatus} eq 'offline') {
    $self->add_critical();
  }
  foreach (@{$self->{phycsical_drives}}) {
    $_->check();
  }
  
}


package Classes::Quantum::I40I80::Components::PhysicalDrive;
our @ISA = qw(Monitoring::GLPlugin::SNMP::TableItem);
use strict;

sub check {
  my $self = shift;
  $self->{phDriveIndex} ||= $self->{flat_indices};
  $self->add_info(sprintf 'drive %d states: online=%s readyness=%s ras=%s cleaning=%s',
      $self->{phDriveIndex}, $self->{phDriveOnlineState},
      $self->{phDriveReadinessState}, $self->{phDriveRasStatus}, $self->{phDriveCleaningStatus});
  if ($self->{phDriveOnlineState} =~ /pending/i) {
    $self->set_level_warning();
  } elsif ($self->{phDriveOnlineState} eq 'offline') {
    $self->set_level_critical();
  }
  if ($self->{phDriveReadinessState} eq 'notReady') {
    $self->set_level_critical();
  }
  if ($self->{phDriveRasStatus} eq 'degraded' or $self->{phDriveRasStatus} eq 'warning') {
    $self->set_level_warning();
  } elsif ($self->{phDriveRasStatus} eq 'unknown') {
    $self->set_level_unknown();
  } elsif ($self->{phDriveRasStatus} eq 'good' or $self->{phDriveRasStatus} eq 'informational') {
  } else {
    $self->set_level_critical();
  }
  if ($self->{phDriveCleaningStatus} eq 'recommended') {
    $self->set_level_warning();
  } elsif ($self->{phDriveCleaningStatus} eq 'required') {
    $self->set_level_critical();
  }
  if ($self->get_level()) {
    $self->add_message($self->get_level());
  }
}


package Classes::Quantum::I40I80;
our @ISA = qw(Classes::Quantum);
use strict;

sub init {
  my $self = shift;
  if ($self->mode =~ /device::hardware::health/) {
    $self->analyze_and_check_environmental_subsystem('Classes::Quantum::I40I80::Components::EnvironmentalSubsystem');
    $self->analyze_and_check_drive_subsystem('Classes::Quantum::I40I80::Components::DriveSubsystem');
    $self->analyze_and_check_logical_subsystem('Classes::Quantum::I40I80::Components::LogicalLibrarySubsystem');
    if (! $self->check_messages()) {
      $self->add_ok('hardware working fine');
    }
  } else {
    $self->no_such_mode();
  }
}

package Classes::Quantum;
our @ISA = qw(Classes::Device);
use strict;

use constant trees => (
    '1.3.6.1.4.1.3697', # QUANTUM-SMALL-TAPE-LIBRARY-MIB
);

sub init {
  my $self = shift;
  if ($self->get_snmp_object('QUANTUM-SMALL-TAPE-LIBRARY-MIB', 'libraryModel', 0) && $self->get_snmp_object('QUANTUM-SMALL-TAPE-LIBRARY-MIB', 'libraryModel', 0) =~ /Scalar\s+i\d+/i) {
    bless $self, 'Classes::Quantum::I40I80';
    $self->debug('using Classes::Quantum::I40I80');
  }
  if (ref($self) ne "Classes::Quantum") {
    $self->init();
  }
}

package Classes::HP::SEMIMIB::Components::EnvironmentalSubsystem;
our @ISA = qw(Monitoring::GLPlugin::SNMP::Item);
use strict;

sub init {
  my $self = shift;
  $self->{'hpHttpMgHealth'} =
      $self->get_snmp_object('SEMI-MIB', 'hpHttpMgHealth');
  $self->get_snmp_tables('SEMI-MIB', [
      ['devices', 'hpHttpMgDeviceTable', 'Classes::HP::StoreEver::Device'],
  ]);
}

sub check {
  my $self = shift;
  $self->add_info('checking overall system');
  if (!@{$self->{devices}}) {
    $self->add_info(sprintf 'status of device is %s', 
        $self->{'hpHttpMgHealth'});
    if ($self->{'hpHttpMgHealth'} eq 'unknown') {
      $self->add_unknown();
    } elsif ($self->{'hpHttpMgHealth'} eq 'ok') {
      $self->add_ok();
    } elsif ($self->{'hpHttpMgHealth'} eq 'warning') {
      $self->add_warning();
    } else {
      $self->add_critical();
    }
  } else {
    foreach (@{$self->{devices}}) {
      $_->check();
    }
  }
  $self->dump()
      if $self->opts->verbose >= 2;
}


package Classes::HP::StoreEver::Device;
our @ISA = qw(Monitoring::GLPlugin::SNMP::TableItem);
use strict;

sub check {
  my $self = shift;
  $self->add_info(sprintf 'device %s (%s %s, sn:%s) status is %s',
      $self->{hpHttpMgDeviceIndex},
      $self->{hpHttpMgDeviceManufacturer},
      $self->{hpHttpMgDeviceProductName},
      $self->{hpHttpMgDeviceSerialNumber},
      $self->{hpHttpMgDeviceHealth});
  if ($self->{hpHttpMgDeviceHealth} eq 'warning') {
    $self->add_warning();
  } elsif ($self->{hpHttpMgDeviceHealth} eq 'unknown') {
    $self->add_unknown();
  } elsif ($self->{hpHttpMgDeviceHealth} eq 'unused') {
  } elsif ($self->{hpHttpMgDeviceHealth} ne 'ok') {
    $self->add_critical();
  } else {
    $self->add_ok();
  }
}


package Classes::HP::SEMIMIB;
our @ISA = qw(Classes::HP);
use strict;

sub init {
  my $self = shift;
  if ($self->mode =~ /device::hardware::health/) {
    $self->analyze_and_check_environmental_subsystem('Classes::HP::SEMIMIB::Components::EnvironmentalSubsystem');
  } else {
    $self->no_such_mode();
  }
}
package Classes::HP;
our @ISA = qw(Classes::Device);
use strict;

use constant trees => (
    '1.3.6.1.4.1.11.2.36', # HP-httpManageable-MIB
);

sub init {
  my $self = shift;
  if ($self->{productname} =~ /StoreEver/i) {
    bless $self, 'Classes::HP::SEMIMIB';
    $self->debug('using Classes::HP::SEMIMIB');
  } else {
    $self->no_such_model();
  }
  if (ref($self) ne "Classes::HP") {
    $self->init();
  }
}

package Classes::Spectralogic::TSeries::T950::Components::EnvironmentalSubsystem;
our @ISA = qw(Monitoring::GLPlugin::SNMP::Item);
use strict;

sub init {
  my $self = shift;
  $self->get_snmp_objects('SL-HW-LIB-T950-MIB', (qw(
      slT950GeneralStatusPowerStatus
      slT950GeneralStatusFansStatus
      slT950GeneralStatusTap1Status
      slT950GeneralStatusTap2Status
  )));
  $self->get_snmp_tables('SL-HW-LIB-T950-MIB', [
    ['partitions', 'slT950GeneralStatusPartitionTable', 'Monitoring::GLPlugin::SNMP::TableItem' ],
    ['messages', 'slT950MessageTable', 'Classes::Spectralogic::TSeries::T950::Components::EnvironmentalSubsystem::Message' ],
  ]);
  if (grep { ! exists $_->{slT950MessageTime}} @{$self->{messages}}) {
    $self->mult_max_msg_size(63);
    $self->{messages} = [];
    $self->clear_table_cache('SL-HW-LIB-T950-MIB', 'slT950MessageTable');
    # sonst fehlen slT950MessageRemedyText und slT950MessageTime
    $self->get_snmp_tables('SL-HW-LIB-T950-MIB', [
      ['messages', 'slT950MessageTable', 'Classes::Spectralogic::TSeries::T950::Components::EnvironmentalSubsystem::Message' ],
    ]);
  }
}

sub check {
  my $self = shift;
  eval "require Date::Manip";
  if ($@) {
    $self->add_critical('Date::Manip is not installed');
    return;
  }
  if ($self->{slT950GeneralStatusPowerStatus} eq 'failure') {
    $self->add_critical('power supply failure');
  }
  if ($self->{slT950GeneralStatusFansStatus} eq 'warning') {
    $self->add_warning('one or more library fans are impaired or filter is dirty');
  } elsif ($self->{slT950GeneralStatusFansStatus} eq 'failure') {
    $self->add_warning('one or more library fans are missing or filter is plugged');
  }
  if ($self->{slT950GeneralStatusTap1Status} eq 'warning') {
    $self->add_warning('tap 1 is open');
  } elsif ($self->{slT950GeneralStatusTap1Status} eq 'failure') {
    $self->add_warning('tap 1 is impaired');
  }
  if ($self->{slT950GeneralStatusTap2Status} eq 'warning') {
    $self->add_warning('tap 2 is open');
  } elsif ($self->{slT950GeneralStatusTap2Status} eq 'failure') {
    $self->add_warning('tap 2 is impaired');
  }
  foreach (@{$self->{messages}}) {
    $_->check();
  }
}


package Classes::Spectralogic::TSeries::T950::Components::EnvironmentalSubsystem::Message;
our @ISA = qw(Monitoring::GLPlugin::SNMP::TableItem);
use strict;

sub check {
  my $self = shift;
  # slT950MessageTime = SLTimeStampString 
  #    YYYY-MM-DD hh:mm:ss where^M
  #    YYYY  four digit year^M
  #    MM    two digit month, zero padded if necessary^M
  #    DD    two digit day, zero padded if necessary^M
  #    hh    two digit, 24 hr clock hour, zero padded if necessary^M
  #    mm    two digit minute, zero padded if necessary^M
  #    ss    two digit second, zero padded if necessary^M
  #    For example, 2005-05-13 23:01:30 would represent 11:01:30 pm^M
  #    on May 13, 2005"^M
  my $date = new Date::Manip::Date;
  $date->parse_format("%Y-%m-%d %H:%M:%S", $self->{slT950MessageTime});
  my $age = time - $date->printf("%s");
  if ($age < 3600) {
    if ($self->{slT950MessageSeverity} eq 'warning') {
      $self->add_warning(sprintf "alarm: %s (%d min ago, %s)",
          $self->{slT950MessageText}, $age / 60, $self->{slT950MessageRemedyText});
    } elsif ($self->{slT950MessageSeverity} eq 'error' ||
        $self->{slT950MessageSeverity} eq 'fatal') {
      $self->add_critical(sprintf "alarm: %s (%d min ago, %s)",
          $self->{slT950MessageText}, $age / 60, $self->{slT950MessageRemedyText});
    }
  }
}


package Classes::Spectralogic::TSeries::T950;
our @ISA = qw(Classes::Spectralogic::TSeries);
use strict;

sub init {
  my $self = shift;
  if ($self->mode =~ /device::hardware::health/) {
    $self->analyze_and_check_environmental_subsystem('Classes::Spectralogic::TSeries::T950::Components::EnvironmentalSubsystem');
    if (! $self->check_messages()) {
      $self->add_ok('hardware working fine');
    }
  } else {
    $self->no_such_mode();
  }
}

package Classes::Spectralogic::TSeries;
our @ISA = qw(Classes::Spectralogic);
use strict;

sub init {
  my $self = shift;
  if ($self->implements_mib('SL-HW-LIB-T950-MIB')) {
    bless $self, 'Classes::Spectralogic::TSeries::T950';
    $self->debug('using Classes::Spectralogic::TSeries::T950');
  } else {
    $self->no_such_model();
  }
  if (ref($self) ne "Classes::Spectralogic::TSeries") {
    $self->init();
  }
}

package Classes::Spectralogic;
our @ISA = qw(Classes::Device);
use strict;

use constant trees => (
    '1.3.6.1.4.1.3478',
);

package Classes::UCDMIB::Component::MemSubsystem;
our @ISA = qw(Monitoring::GLPlugin::SNMP::Item);
use strict;

sub init {
  my $self = shift;
  $self->get_snmp_objects('UCD-SNMP-MIB', (qw(
      memTotalSwap memAvailSwap memTotalReal memAvailReal memTotalFree)));
  # https://kc.mcafee.com/corporate/index?page=content&id=KB73175
  $self->{mem_usage} = ($self->{memTotalReal} - $self->{memTotalFree}) /
      $self->{memTotalReal} * 100;
  $self->{mem_usage} = $self->{memAvailReal} * 100 / $self->{memTotalReal};
}

sub check {
  my $self = shift;
  $self->add_info('checking memory');
  if (defined $self->{mem_usage}) {
    $self->add_info(sprintf 'memory usage is %.2f%%',
        $self->{mem_usage});
    $self->set_thresholds(warning => 80,
        critical => 90);
    $self->add_message($self->check_thresholds($self->{mem_usage}));
    $self->add_perfdata(
        label => 'memory_usage',
        value => $self->{mem_usage},
        uom => '%',
    );
  } else {
    $self->add_unknown('cannot aquire memory usage');
  }
}

package Classes::UCDMIB::Component::CpuSubsystem;
our @ISA = qw(Monitoring::GLPlugin::SNMP::Item);
use strict;

sub init {
  my $self = shift;
  $self->get_snmp_objects('UCD-SNMP-MIB', (qw(
      ssCpuUser ssCpuSystem ssCpuIdle ssCpuRawUser ssCpuRawSystem ssCpuRawIdle ssCpuRawNice)));
  $self->valdiff({name => 'cpu'}, qw(ssCpuRawUser ssCpuRawSystem ssCpuRawIdle ssCpuRawNice));
  my $cpu_total = $self->{delta_ssCpuRawUser} + $self->{delta_ssCpuRawSystem} +
      $self->{delta_ssCpuRawIdle} + $self->{delta_ssCpuRawNice};
  if ($cpu_total == 0) {
    $self->{cpu_usage} = 0;
  } else {
    $self->{cpu_usage} = (100 - ($self->{delta_ssCpuRawIdle} / $cpu_total) * 100);
  }
}

sub check {
  my $self = shift;
  $self->add_info('checking cpus');
  $self->add_info(sprintf 'cpu usage is %.2f%%', $self->{cpu_usage});
  $self->set_thresholds(warning => 50, critical => 90);
  $self->add_message($self->check_thresholds($self->{cpu_usage}));
  $self->add_perfdata(
      label => 'cpu_usage',
      value => $self->{cpu_usage},
      uom => '%',
  );
}

sub unix_init {
  my $self = shift;
  my %params = @_;
  my $type = 0;
  $self->get_snmp_tables('UCD-SNMP-MIB', [
      ['loads', 'laTable', 'Classes::UCDMIB::Component::CpuSubsystem::Load'],
  ]);
}

sub unix_check {
  my $self = shift;
  $self->add_info('checking loads');
  foreach (@{$self->{loads}}) {
    $_->check();
  }
}

sub unix_dump {
  my $self = shift;
  foreach (@{$self->{loads}}) {
    $_->dump();
  }
}


package Classes::UCDMIB::Component::CpuSubsystem::Load;
our @ISA = qw(Monitoring::GLPlugin::SNMP::TableItem);
use strict;

sub check {
  my $self = shift;
  my $errorfound = 0;
  $self->add_info(sprintf '%s is %.2f', lc $self->{laNames}, $self->{laLoadFloat});
  $self->set_thresholds(warning => $self->{laConfig},
      critical => $self->{laConfig});
  $self->add_message($self->check_thresholds($self->{laLoadFloat}));
  $self->add_perfdata(
      label => lc $self->{laNames},
      value => $self->{laLoadFloat},
  );
}

package Classes::UCDMIB;
our @ISA = qw(Classes::Device);
use strict;

package Classes::Adic::Components::ComponentSubsystem;
our @ISA = qw(Monitoring::GLPlugin::SNMP::Item);
use strict;

sub init {
  my $self = shift;
  $self->get_snmp_tables('ADIC-INTELLIGENT-STORAGE-MIB', [
    ['components', 'componentTable', 'Classes::Adic::Components::ComponentSubsystem::Component'],
    #['powersupplies', 'powerSupplyTable', 'Monitoring::GLPlugin::TableItem'],
    #['voltages', 'voltageSensorTable', 'Monitoring::GLPlugin::TableItem'],
    #['temperatures', 'temperatureSensorTable', 'Monitoring::GLPlugin::TableItem'],
    #['fans', 'coolingFanTable', 'Monitoring::GLPlugin::TableItem'],
  ]);
}


package Classes::Adic::Components::ComponentSubsystem::Component;
our @ISA = qw(Monitoring::GLPlugin::SNMP::TableItem);
use strict;

sub check {
  my $self = shift;
  $self->add_info(sprintf 'component %s is %s and %s',
      $self->{componentDisplayName}, $self->{componentControl},
      $self->{componentStatus});
  if ($self->{componentControl} eq 'online') {
    if ($self->{componentStatus} eq 'failed') {
      $self->add_critical();
    } elsif ($self->{componentStatus} eq 'warning') {
      $self->add_warning();
    } elsif ($self->{componentStatus} eq 'unknown') {
      $self->add_unknown();
    } # else ok oder unused
  }
if (ref($self) =~ /rasSystemStatusTable/) {
 $self->{rasStatusGroupLastChange};
}
}


package Classes::Adic::Components::EnvironmentalSubsystem;
our @ISA = qw(Monitoring::GLPlugin::SNMP::Item);
use strict;

sub init {
  my $self = shift;
  $self->get_snmp_objects('ADIC-INTELLIGENT-STORAGE-MIB', (qw(
      productName productDisplayName productDescription
      productVendor productVersion productDisplayVersion
      productLibraryClass productSerialNumber
      agentGlobalStatus agentLastGlobalStatus agentTimeStamp 
  )));
  #$self->analyze_and_check_environmental_subsystem('Classes::Adic::Components::ComponentSubsystem');
  $self->analyze_and_check_environmental_subsystem('Classes::Adic::Components::RasSubsystem');
}

sub dump {
  my $self = shift;
  printf "[ENVIRONMENTALSUBSYSTEM]\n";
  foreach (qw(
      productName productDisplayName productDescription
      productVendor productVersion productDisplayVersion
      productLibraryClass productSerialNumber
      agentGlobalStatus agentLastGlobalStatus agentTimeStamp)) {
    printf "%s: %s\n", $_, $self->{$_};
  }
}

package Classes::Adic::Components::RasSubsystem;
our @ISA = qw(Monitoring::GLPlugin::SNMP::Item);
use strict;

sub init {
  my $self = shift;
  use Data::Dumper;
  $self->get_snmp_tables('ADIC-MANAGEMENT-MIB', [
    ['rassystems', 'rasSystemStatusTable', 'Classes::Adic::Components::RasSubsystem::RasSystem'],
  ]);
}

package Classes::Adic::Components::RasSubsystem::RasSystem;
our @ISA = qw(Monitoring::GLPlugin::SNMP::TableItem);
use strict;

sub finish {
  my $self = shift;
  eval {
    $self->{rasStatusGroupLastChangeHuman} = 
        scalar localtime $self->{rasStatusGroupLastChange};
  };
  if ($@) {
    $self->{rasStatusGroupLastChangeHuman} = '_unknown_';
  }
}


sub check {
  my $self = shift;
  $self->{rasStatusGroupTextSummary} =~ s/[\|'"]+/_/g;
  if ($self->{rasStatusGroupStatus} eq 'good' ||
      $self->{rasStatusGroupStatus} eq 'informational') {
    $self->add_info(sprintf '%s has status %s',
        $self->{rasStatusGroupIndex}, $self->{rasStatusGroupStatus});
  } else {
    $self->add_info(sprintf '%s has status %s%s%s',
        $self->{rasStatusGroupIndex}, $self->{rasStatusGroupStatus},
        $self->{rasStatusGroupTextSummary} ? 
            sprintf(' (%s)', $self->{rasStatusGroupTextSummary}) : '',
        $self->{rasStatusGroupLastChangeHuman} ne '_unknown_' ?
            sprintf(' since %s', $self->{rasStatusGroupLastChangeHuman}) : ''
    );
    if ($self->{rasStatusGroupStatus} eq 'failed') {
      $self->add_critical();
    } elsif ($self->{rasStatusGroupStatus} eq 'degraded') {
      $self->add_warning();
    } elsif ($self->{rasStatusGroupStatus} eq 'warning') {
      $self->add_warning();
    } elsif ($self->{rasStatusGroupStatus} eq 'unknown') {
      $self->add_unknown();
    } elsif ($self->{rasStatusGroupStatus} eq 'invalid') {
      $self->add_unknown();
    } # else ok oder unused
  }
}

package Classes::Adic;
our @ISA = qw(Classes::Device);

sub init {
  my $self = shift;
  #      ADIC-INTELLIGENT-STORAGE-MIB     ADIC-MANAGEMENT-MIB
  # alt  1.31 1.32 1.33                   1.92 1.93
  # neu  1.18 1.19 1.20 1.21 1.22 1.23    1.38 1.41 1.42 1.43 1.44 1.45
  $self->get_snmp_objects('ADIC-INTELLIGENT-STORAGE-MIB', (qw(productMibVersion)));
  # steckt in intell-stor-mib, meint aber version von mgmgt-mib
  $self->require_mib('ADIC-INTELLIGENT-STORAGE-MIB');
  $self->require_mib('ADIC-MANAGEMENT-MIB');
  if (grep { $self->{productMibVersion} eq $_ } qw(1.18 1.19 1.20 1.21 1.22 1.23)) {
    $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{'ADIC-INTELLIGENT-STORAGE-MIB'} =
        $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{'ADIC-INTELLIGENT-STORAGE-MIB::1.33'};
    $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{'ADIC-MANAGEMENT-MIB'} =
        $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{'ADIC-MANAGEMENT-MIB::1.93'};
    $Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{'ADIC-INTELLIGENT-STORAGE-MIB'} =
        $Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{'ADIC-INTELLIGENT-STORAGE-MIB::1.33'};
    $Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{'ADIC-MANAGEMENT-MIB'} =
        $Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{'ADIC-MANAGEMENT-MIB::1.93'};
  } else {
    $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{'ADIC-INTELLIGENT-STORAGE-MIB'} =
        $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{'ADIC-INTELLIGENT-STORAGE-MIB::1.23'};
    $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{'ADIC-MANAGEMENT-MIB'} =
        $Monitoring::GLPlugin::SNMP::MibsAndOids::mibs_and_oids->{'ADIC-MANAGEMENT-MIB::1.45'};
    $Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{'ADIC-INTELLIGENT-STORAGE-MIB'} =
        $Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{'ADIC-INTELLIGENT-STORAGE-MIB::1.23'};
    $Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{'ADIC-MANAGEMENT-MIB'} =
        $Monitoring::GLPlugin::SNMP::MibsAndOids::definitions->{'ADIC-MANAGEMENT-MIB::1.45'};
  }
  if ($self->mode =~ /device::hardware::health/) {
    $self->analyze_and_check_environmental_subsystem('Classes::Adic::Components::EnvironmentalSubsystem');
    if (! $self->check_messages()) {
      $self->add_ok('hardware working fine');
    }
  } elsif ($self->mode =~ /device::hardware::load/) {
    $self->analyze_and_check_and_check_cpu_subsystem("Classes::UCDMIB::Component::CpuSubsystem");
  } elsif ($self->mode =~ /device::hardware::memory/) {
    $self->analyze_and_check_and_check_mem_subsystem("Classes::UCDMIB::Component::MemSubsystem");
  } else {
    $self->no_such_mode();
  }
}
# 

package Classes::BDT::FlexStorII::Components::EnvironmentalSubsystem;
our @ISA = qw(Monitoring::GLPlugin::SNMP::Item);
use strict;

sub init {
  my $self = shift;
  $self->get_snmp_objects('BDT-MIB', (qw(
      bDTGlobalStatus
      bDTDisplayName
      bDTDescription 
      bDTAgentVendor
      bDTAgentVersion
      bDTGlobalData
      bDTGlobalStatus
      bDTGlobalStatusDefinition
      bDTLastGlobalStatus
      bDTLastGlobalStatusDefinition
      bDTTimeStamp
      bDTGetTimeOut
      bDTErrorCode
      bDTRefreshRate
      bDTErrorData
      bDTDeviceInfo
      bDTDevSerialNumber
      bDTDevVendorID
      bDTDevProductID
      bDTDevFirmwareRev
      bDTDevRobFirmwareRev
      bDTDevBootcodeRev
  )));
}

sub check {
  my $self = shift;
  $self->add_info(sprintf "%sstatus is %s", 
      ($self->{bDTDisplayName} ? $self->{bDTDisplayName}." " : ""),
      $self->{bDTGlobalStatus});
  if ($self->{bDTGlobalStatus} =~ /other|unknown/) {
    $self->add_unknown();
  } elsif ($self->{bDTGlobalStatus} eq "ok") {
    $self->add_ok();
  } elsif ($self->{bDTGlobalStatus} eq "non-critical") {
    $self->annotate_info(sprintf "error: %s code: %s serial: %s",
        $self->{bDTErrorData}, $self->{bDTErrorCode}, $self->{bDTDevSerialNumber});
    $self->add_warning();
  } else {
    $self->annotate_info(sprintf "error: %s code: %s serial: %s",
        $self->{bDTErrorData}, $self->{bDTErrorCode}, $self->{bDTDevSerialNumber});
    $self->add_critical();
  }
}

package Classes::BDT::FlexStorII;
our @ISA = qw(Classes::BDT);
use strict;

sub init {
  my $self = shift;
  if ($self->mode =~ /device::hardware::health/) {
    $self->analyze_and_check_environmental_subsystem('Classes::BDT::FlexStorII::Components::EnvironmentalSubsystem');
    if (! $self->check_messages()) {
      $self->add_ok('hardware working fine');
    }
  } else {
    $self->no_such_mode();
  }
}


package Classes::BDT;
our @ISA = qw(Classes::Device);
use strict;

sub init {
  my $self = shift;
  if ($self->{productname} =~ /FlexStor II/i) {
    bless $self, 'Classes::BDT::FlexStorII';
    $self->debug('using Classes::BDT::FlexStorII');
  } else {
    $self->no_such_model();
  }
  if (ref($self) ne "Classes::BDT") {
    $self->init();
  }
}
package Classes::Device;
our @ISA = qw(Monitoring::GLPlugin::SNMP);
use strict;

sub classify {
  my $self = shift;
  if (! ($self->opts->hostname || $self->opts->snmpwalk)) {
    $self->add_unknown('either specify a hostname or a snmpwalk file');
  } else {
    $self->check_snmp_and_model();
    if ($self->opts->servertype) {
      $self->{productname} = 'storeever' if $self->opts->servertype eq 'storeever';
    }
    if (! $self->check_messages()) {
      if ($self->opts->verbose && $self->opts->verbose) {
        printf "I am a %s\n", $self->{productname};
      }
      if ($self->opts->mode =~ /^my-/) {
        $self->load_my_extension();
      } elsif ($self->{productname} =~ /(1\/8 G2)|(^ hp )|(storeever)/i) {
        bless $self, 'Classes::HP';
        $self->debug('using Classes::HP');
      } elsif ($self->implements_mib('SEMI-MIB')) {
        bless $self, 'Classes::HP::SEMIMIB';
        $self->debug('using Classes::HP::SEMIMIB');
      } elsif ($self->get_snmp_object('QUANTUM-SMALL-TAPE-LIBRARY-MIB', 'libraryVendor', 0)) {
        bless $self, 'Classes::Quantum';
        $self->debug('using Classes::Quantum');
      } elsif ($self->implements_mib('SPECTRALOGIC-GLOBAL-REG-SLHARDWARE-SLLIBRARIES-SLTSERIES')) {
        bless $self, 'Classes::Spectralogic::TSeries';
        $self->debug('using Classes::Spectralogic::TSeries');
      } elsif ($self->implements_mib('ADIC-INTELLIGENT-STORAGE-MIB')) {
        bless $self, 'Classes::Adic';
        $self->debug('using Adic');
      } elsif ($self->implements_mib('BDT-MIB')) {
        bless $self, 'Classes::BDT';
        $self->debug('using BDT');
      } else {
        if (my $class = $self->discover_suitable_class()) {
          bless $self, $class;
          $self->debug('using '.$class);
        } else {
          bless $self, 'Classes::Generic';
          $self->debug('using Classes::Generic');
        }
      }
    }
  }
  return $self;
}


package Classes::Generic;
our @ISA = qw(Classes::Device);
use strict;

sub init {
  my $self = shift;
  if ($self->mode =~ /something specific/) {
  } else {
    bless $self, 'Monitoring::GLPlugin::SNMP';
    $self->no_such_mode();
  }
}

package main;
#! /usr/bin/perl

use strict;
no warnings qw(once);


eval {
  if ( ! grep /AUTOLOAD/, keys %Monitoring::GLPlugin::) {
    require Monitoring::GLPlugin;
    require Monitoring::GLPlugin::SNMP;
  }
};
if ($@) {
  printf "UNKNOWN - module Monitoring::GLPlugin was not found. Either build a standalone version of this plugin or set PERL5LIB\n";
  printf "%s\n", $@;
  exit 3;
}

my $plugin = Classes::Device->new(
    shortname => '',
    usage => 'Usage: %s [ -v|--verbose ] [ -t <timeout> ] '.
        '--mode <what-to-do> '.
        '--hostname <network-component> --community <snmp-community>'.
        '  ...]',
    version => '$Revision: 1.4.0.1 $',
    blurb => 'This plugin checks various parameters of tape libraries ',
    url => 'http://labs.consol.de/nagios/check_tl_health',
    timeout => 60,
);
$plugin->add_mode(
    internal => 'device::hardware::health',
    spec => 'hardware-health',
    alias => undef,
    help => 'Check the status of environmental equipment (fans, temperatures, power, selftests)',
);
$plugin->add_snmp_modes();
$plugin->add_snmp_args();
$plugin->add_default_args();

$plugin->getopts();
$plugin->classify();
$plugin->validate_args();

if (! $plugin->check_messages()) {
  $plugin->init();
  if (! $plugin->check_messages()) {
    $plugin->add_ok($plugin->get_summary())
        if $plugin->get_summary();
    $plugin->add_ok($plugin->get_extendedinfo(" "))
        if $plugin->get_extendedinfo();
  }
}
my ($code, $message) = $plugin->opts->multiline ?
    $plugin->check_messages(join => "\n", join_all => ', ') :
    $plugin->check_messages(join => ', ', join_all => ', ');
$message .= sprintf "\n%s\n", $plugin->get_info("\n")
    if $plugin->opts->verbose >= 1;
#printf "%s\n", Data::Dumper::Dumper($plugin);
$plugin->nagios_exit($code, $message);
