/**
  * Second version of the <code>execute</code> methods.<br>
  * <br>
  * This method returns <code>false</code>, if the request does not match according to the contract
  * of {@link #canHandle}. This never happens under normal conditions since the {@link
  * InteractionHandler} does not call <code>execute</code>, if {@link #canHandle} returns <code>
  * false</code>. <br>
  * <br>
  * Otherwise, this method fills the response <code>Record</code> with the specified response
  * <code>Map</code> data. Use the <code>setResponse</code> methods that take a <code>Map</code> to
  * prepare the response <code>Map</code>. The response <code>Record</code> must implement <code>
  * MappedRecord</code> (it does, otherwise the request would have been rejected by {@link
  * #canHandle}). If no response <code>Map</code> is specified at all, the response <code>Record
  * </code> is not touched but <code>true</code> is returned anyway
  *
  * @param interactionSpec the interaction spec
  * @param actualRequest the actual request
  * @param actualResponse the actual response
  * @return <code>true</code> under normal conditions
  */
 public boolean execute(
     InteractionSpec interactionSpec, Record actualRequest, Record actualResponse)
     throws ResourceException {
   if (!canHandle(interactionSpec, actualRequest, actualResponse)) return false;
   try {
     if (null != responseData && null != actualResponse) {
       ((MappedRecord) actualResponse).clear();
       ((MappedRecord) actualResponse).putAll(responseData);
     }
   } catch (Exception exc) {
     ResourceException resExc = new ResourceException("execute() failed");
     resExc.setLinkedException(exc);
     throw resExc;
   }
   return true;
 }
 /**
  * First version of the <code>execute</code> methods.<br>
  * <br>
  * This method returns <code>null</code>, if the request does not match according to the contract
  * of {@link #canHandle}. This never happens under normal conditions since the {@link
  * InteractionHandler} does not call <code>execute</code>, if {@link #canHandle} returns <code>
  * false</code>. <br>
  * <br>
  * Otherwise, this method returns the specified response. If a response <code>Record</code> object
  * is specified (use {@link #setResponse(Record)}), it always takes precedence, i.e. the response
  * <code>Map</code> will be ignored. If no <code>Record</code> object is specified, a <code>Record
  * </code> object is created and filled with the specified response <code>Map</code> data. Use the
  * <code>setResponse</code> methods that take a <code>Map</code> to prepare the response <code>Map
  * </code>. The created <code>Record</code> is of the the specified type (the <code>setResponse
  * </code> method that takes a second <code>Class</code> parameter allows for specifying a type).
  * If no type is specified, a {@link com.mockrunner.mock.connector.cci.MockMappedRecord} is
  * created. If no response <code>Map</code> is specified at all, an empty {@link
  * com.mockrunner.mock.connector.cci.MockMappedRecord} will be returned.
  *
  * @param interactionSpec the interaction spec
  * @param actualRequest the actual request
  * @return the response according to the current request
  */
 public Record execute(InteractionSpec interactionSpec, Record actualRequest)
     throws ResourceException {
   if (!canHandle(interactionSpec, actualRequest, null)) return null;
   if (null != responseRecord) return responseRecord;
   MappedRecord response = null;
   try {
     if (null == responseClass) {
       response = new MockMappedRecord();
     } else {
       response = (MappedRecord) responseClass.newInstance();
     }
     if (null != responseData) {
       response.putAll(responseData);
     }
   } catch (Exception exc) {
     ResourceException resExc = new ResourceException("execute() failed");
     resExc.setLinkedException(exc);
     throw resExc;
   }
   return (Record) response;
 }
 private boolean doesRequestMatch(Record request) {
   if (null == expectedRequest) return true;
   if (null == request) return false;
   if (request instanceof MappedRecord) {
     try {
       MappedRecord mappedRequest = (MappedRecord) request;
       if (mappedRequest.size() != expectedRequest.size()) return false;
       Iterator keys = mappedRequest.keySet().iterator();
       while (keys.hasNext()) {
         Object nextKey = keys.next();
         Object actualValue = mappedRequest.get(nextKey);
         Object expectedValue = expectedRequest.get(nextKey);
         if (!areObjectsEquals(actualValue, expectedValue)) {
           return false;
         }
       }
       return true;
     } catch (Exception exc) {
       throw new NestedApplicationException(exc);
     }
   }
   return false;
 }