/**
   * parse Server - Parse load balancing virtual server configuration object obtained from the
   * NetScaler appliance and create a VirtualApplication and discovery extension.
   *
   * @param vServer Configuration for Load Balancing Virtual Server resource from the NetScaler
   *     appliance
   * @return VirtualApplication object
   */
  private VirtualApplication parseServer(lbvserver vServer) {

    if (logger.isTraceEnabled()) logger.trace(logPrefix + vServer);

    // Retrieve load balancing virtual server information
    String vServerName, vServerUuid, vServerIP, vServerType;
    int vServerPort;
    try {
      vServerName =
          vServer.get_name(); // name of the loading balancing virtual server, is changeable
      vServerIP = vServer.get_ipv46(); // IPv4 or IPv6 address assigned to the virtual server
      vServerPort = vServer.get_port(); // Port number for the virtual server
      vServerUuid = NetScalerUtil.getServerUuid(vServerIP, vServerPort, target); // create uuid
      vServerType =
          vServer.get_servicetype(); // Protocol used by the service (also called the service type)
      lbvserver_ip2serviceName.put(vServerIP, vServerName);
      if (logger.isDebugEnabled())
        logger.debug(
            logPrefix
                + "Load Balancing Server IP:: "
                + vServerIP
                + "::port "
                + vServerPort
                + "::service name "
                + vServerName
                + "::service type "
                + vServerType);
    } catch (Exception e) {
      exceptions = true;
      if (logger.isDebugEnabled())
        logger.error(logPrefix + "Failed retrieving virtual server information ", e);
      else logger.error(logPrefix + "Failed retrieving virtual server information " + e);
      NotificationsManagerImpl.vmtMANAGER.createException(
          target, e, NotificationCategory.DISCOVERY, VMTSeverity.MAJOR);
      return null;
    }

    // Get the binding objects for the services bound to each load balancer virtual server on the
    // appliance
    lbvserver_service_binding[] bindObjs =
        NetScalerUtil.getBoundServices(
            session, vServerName,
            target, logPrefix);
    if (logger.isTraceEnabled()) {
      int length = (bindObjs == null) ? 0 : bindObjs.length;
      logger.trace(
          logPrefix
              + "Load Balancing Server "
              + vServerName
              + " has "
              + length
              + " bound services");
    }

    // get application services information
    ip2port2serviceName.clear();
    ip2NameIPPort.clear();
    if (bindObjs != null) {
      for (lbvserver_service_binding bind : bindObjs) {
        String serviceIP, serviceName;
        Integer servicePort;
        try {
          serviceIP = bind.get_ipv46();
          serviceName = bind.get_servicename();
          servicePort = bind.get_port();
          // this info is needed to find and attach the applications objects
          // from the topology during post processing
          Map<Integer, String> port2name = new HashMap<Integer, String>();
          ip2port2serviceName.put(serviceIP, port2name);
          port2name.put(servicePort, serviceName);
          // we need this info (app service name::IP::Port) for saving in the gslb vApp
          ip2NameIPPort.put(serviceIP, serviceName + "::" + serviceIP + "::" + servicePort);
        } catch (Exception e) {
          exceptions = true;
          if (logger.isDebugEnabled())
            logger.error(
                logPrefix
                    + "Failed retrieving services information for virtual server with name "
                    + vServerName
                    + " ",
                e);
          else
            logger.error(
                logPrefix
                    + "Failed retrieving services information for virtual server with name "
                    + vServerName
                    + " "
                    + e);
          NotificationsManagerImpl.vmtMANAGER.createException(
              target, e, NotificationCategory.DISCOVERY, VMTSeverity.MINOR);
          continue;
        }
      }
    }
    if (logger.isDebugEnabled()) {
      logger.debug(
          logPrefix + "on lbvserver: " + vServerName + " app services ---> " + ip2NameIPPort);
      logger.debug(
          logPrefix + "on lbvserver: " + vServerName + " app services ---> " + ip2port2serviceName);
    }
    // whether to create vApp for this lbvserver VIP or not depends if it is managed by the gslb,
    // check if this VIP is in the service bindings for the gslb service configured on this target
    boolean createVApp = true;
    if (lbvServerVIPToGslbVAppMap.containsKey(vServerIP)) {
      // found this Virtual IP on this target
      // don't create the vApp for this lbvserver,
      createVApp = false;
      // Save all the application services info in the associated gslb vApp
      updateGslbVAppAgent(vServerIP, vServerPort);
    }

    // ------------ create objects ----------
    if (createVApp) {
      // Create the VirtualApplication object corresponding to the load balancing virtual server
      // discovered in NetScaler
      VirtualApplication lb =
          (VirtualApplication)
              createObject(
                  AbstractionPackage.eINSTANCE.getVirtualApplication(),
                  "VApp-" + vServerName,
                  vServerUuid);
      // create VirtualApp Discovery extension
      NetScalerVirtualAppDiscExt vServerExt =
          (NetScalerVirtualAppDiscExt)
              lb.createExtension(
                  DiscoveryExtensionsPackage.eINSTANCE.getNetScalerVirtualAppDiscExt());
      // set the properties for the vApp and discovery extension and also save the app services info
      // in the discovery extension
      return createVirtualApplication(
          lb,
          target,
          vServerExt,
          vServerName,
          vServerIP,
          vServerPort, // lbverserver's service name, ip and port
          vServerUuid,
          vServerType,
          ip2port2serviceName, // mappings of the connected services
          NetScalerUtil.LB_VSERVER // "lbvserver"
          );
    }

    return null;
  } // end parse server