/** Set the standard request controls */
 private void setRequestControls(byte[] cookie) throws TranslatorException {
   List<Control> ctrl = new ArrayList<Control>();
   SortKey[] keys = searchDetails.getSortKeys();
   try {
     if (keys != null) {
       ctrl.add(new SortControl(keys, Control.NONCRITICAL));
     }
     if (this.executionFactory.usePagination()) {
       ctrl.add(
           new PagedResultsControl(
               this.executionContext.getBatchSize(), cookie, Control.CRITICAL));
     }
     if (!ctrl.isEmpty()) {
       this.ldapCtx.setRequestControls(ctrl.toArray(new Control[ctrl.size()]));
       LogManager.logTrace(
           LogConstants.CTX_CONNECTOR,
           "Sort/pagination controls were created successfully."); //$NON-NLS-1$
     }
   } catch (NamingException ne) {
     final String msg =
         LDAPPlugin.Util.getString("LDAPSyncQueryExecution.setControlsError")
             + //$NON-NLS-1$
             " : "
             + ne.getExplanation(); // $NON-NLS-1$
     throw new TranslatorException(ne, msg);
   } catch (IOException e) {
     throw new TranslatorException(e);
   }
 }
 /**
  * Perform the LDAP search against the subcontext, using the filter and search controls
  * appropriate to the query and model metadata.
  */
 private void executeSearch() throws TranslatorException {
   String filter = searchDetails.getContextFilter();
   try {
     searchEnumeration = this.ldapCtx.search("", filter, ctrls); // $NON-NLS-1$
   } catch (NamingException ne) {
     final String msg =
         LDAPPlugin.Util.getString("LDAPSyncQueryExecution.execSearchError"); // $NON-NLS-1$
     throw new TranslatorException(ne, msg + " : " + ne.getExplanation()); // $NON-NLS-1$
   } catch (Exception e) {
     final String msg =
         LDAPPlugin.Util.getString("LDAPSyncQueryExecution.execSearchError"); // $NON-NLS-1$
     throw new TranslatorException(e, msg);
   }
 }
 // GHH 20080326 - replaced existing implementation with the same
 // code as used by cancel method.  First try to
 // close the searchEnumeration, then the search context
 // We are very conservative when closing the enumeration
 // but less so when closing context, since it is safe to call close
 // on contexts multiple times
 @Override
 public void close() {
   if (searchEnumeration != null) {
     try {
       searchEnumeration.close();
     } catch (Exception e) {
     } // catch everything, because NamingEnumeration has undefined behavior if it previously hit
       // an exception
   }
   if (ldapCtx != null) {
     try {
       ldapCtx.close();
     } catch (NamingException ne) {
       LogManager.logWarning(
           LogConstants.CTX_CONNECTOR,
           LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12003, ne.getExplanation()));
     }
   }
 }
  // GHH 20080326 - added resultDistinguishedName to method signature.  If
  // there is an element in the model named "DN" and there is no attribute
  // with this name in the search result, we return this new parameter
  // value for that column in the result
  // GHH 20080326 - added handling of ClassCastException when non-string
  // attribute is returned
  private Object getValue(
      Column modelElement, SearchResult result, Attributes attrs, boolean unwrap)
      throws TranslatorException, InvalidNameException {

    String modelAttrName = modelElement.getSourceName();
    Class<?> modelAttrClass = modelElement.getJavaType();

    String multivalAttr = modelElement.getDefaultValue();

    if (modelAttrName == null) {
      final String msg =
          LDAPPlugin.Util.getString("LDAPSyncQueryExecution.nullAttrError"); // $NON-NLS-1$
      throw new TranslatorException(msg);
    }

    Attribute resultAttr = attrs.get(modelAttrName);

    // If the attribute is not present, we return NULL.
    if (resultAttr == null) {
      // GHH 20080326 - return DN from input parameter
      // if DN attribute is not present in search result
      if (modelAttrName.equalsIgnoreCase("DN")) { // $NON-NLS-1$
        return result.getNameInNamespace();
      }
      return null;
    }
    Object objResult = null;
    try {
      if (TypeFacility.RUNTIME_TYPES.STRING.equals(modelAttrClass)
          && MULTIVALUED_CONCAT.equalsIgnoreCase(multivalAttr)) {
        // mpw 5/09
        // Order the multi-valued attrs alphabetically before creating a single string,
        // using the delimiter to separate each token
        ArrayList<String> multivalList = new ArrayList<String>();
        NamingEnumeration<?> attrNE = resultAttr.getAll();
        int length = 0;
        while (attrNE.hasMore()) {
          String val = (String) attrNE.next();
          multivalList.add(val);
          length += ((val == null ? 0 : val.length()) + 1);
        }
        Collections.sort(multivalList);

        StringBuilder multivalSB = new StringBuilder(length);
        Iterator<String> itr = multivalList.iterator();
        while (itr.hasNext()) {
          multivalSB.append(itr.next());
          if (itr.hasNext()) {
            multivalSB.append(delimiter);
          }
        }
        return multivalSB.toString();
      }
      if (modelAttrClass.isArray()) {
        return getArray(modelAttrClass.getComponentType(), resultAttr, modelElement, modelAttrName);
      }
      if (unwrap && resultAttr.size() > 1) {
        return getArray(modelAttrClass, resultAttr, modelElement, modelAttrName);
      }

      // just a single value
      objResult = resultAttr.get();
    } catch (NamingException ne) {
      final String msg =
          LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12004, modelAttrName)
              + " : "
              + ne.getExplanation(); // $NON-NLS-1$m
      LogManager.logWarning(LogConstants.CTX_CONNECTOR, msg);
      throw new TranslatorException(ne, msg);
    }

    return convertSingleValue(modelElement, modelAttrName, modelAttrClass, objResult);
  }