public void receive(org.apache.axis2.context.MessageContext mc) throws AxisFault {

    boolean traceOn = proxy.getAspectConfiguration().isTracingEnabled();
    boolean traceOrDebugOn = traceOn || log.isDebugEnabled();

    CustomLogSetter.getInstance().setLogAppender(proxy.getArtifactContainerName());

    String remoteAddr =
        (String) mc.getProperty(org.apache.axis2.context.MessageContext.REMOTE_ADDR);

    if (traceOrDebugOn) {
      traceOrDebug(
          traceOn,
          "Proxy Service "
              + name
              + " received a new message"
              + (remoteAddr != null ? " from : " + remoteAddr : "..."));
      traceOrDebug(
          traceOn, ("Message To: " + (mc.getTo() != null ? mc.getTo().getAddress() : "null")));
      traceOrDebug(
          traceOn, ("SOAPAction: " + (mc.getSoapAction() != null ? mc.getSoapAction() : "null")));
      traceOrDebug(
          traceOn, ("WSA-Action: " + (mc.getWSAAction() != null ? mc.getWSAAction() : "null")));

      if (traceOn && trace.isTraceEnabled()) {
        String[] cids = mc.getAttachmentMap().getAllContentIDs();
        if (cids != null && cids.length > 0) {
          for (String cid : cids) {
            trace.trace("With attachment content ID : " + cid);
          }
        }
        trace.trace("Envelope : " + mc.getEnvelope());
      }
    }

    MessageContext synCtx = MessageContextCreatorForAxis2.getSynapseMessageContext(mc);
    Integer statisticReportingIndex = null;
    // Statistic reporting
    boolean isStatisticsEnabled = RuntimeStatisticCollector.isStatisticsEnabled();
    if (isStatisticsEnabled) {
      statisticReportingIndex =
          OpenEventCollector.reportEntryEvent(
              synCtx, this.name, proxy.getAspectConfiguration(), ComponentType.PROXYSERVICE);
    }

    Object inboundServiceParam =
        proxy.getParameterMap().get(SynapseConstants.INBOUND_PROXY_SERVICE_PARAM);
    Object inboundMsgCtxParam = mc.getProperty(SynapseConstants.IS_INBOUND);

    // check whether the message is from Inbound EP
    if (inboundMsgCtxParam == null || !(boolean) inboundMsgCtxParam) {
      // check whether service parameter is set to true or null, then block this request
      if (inboundServiceParam != null && (Boolean.valueOf((String) inboundServiceParam))) {
        /*
        return because same proxy is exposed via InboundEP and service parameter(inbound.only) is set to
        true, which disable normal http transport proxy
        */
        if (!synCtx.getFaultStack().isEmpty()) {
          if (log.isDebugEnabled()) {
            log.debug(
                "Executing fault handler - message discarded due to the proxy is allowed only via InboundEP");
          }
          (synCtx.getFaultStack().pop())
              .handleFault(
                  synCtx,
                  new Exception(
                      "Proxy Service "
                          + name
                          + " message discarded due to the proxy is allowed only via InboundEP"));
        } else {
          if (log.isDebugEnabled()) {
            log.debug(
                "Proxy Service "
                    + name
                    + " message discarded due to the proxy is "
                    + "allowed only via InboundEP");
          }
        }
        return;
      }
    }

    TenantInfoConfigurator configurator = synCtx.getEnvironment().getTenantInfoConfigurator();
    if (configurator != null) {
      configurator.extractTenantInfo(synCtx);
    }
    TransportInDescription trpInDesc = mc.getTransportIn();
    if (trpInDesc != null) {
      synCtx.setProperty(SynapseConstants.TRANSPORT_IN_NAME, trpInDesc.getName());
    }

    // get service log for this message and attach to the message context also set proxy name
    Log serviceLog = LogFactory.getLog(SynapseConstants.SERVICE_LOGGER_PREFIX + name);
    ((Axis2MessageContext) synCtx).setServiceLog(serviceLog);

    synCtx.setProperty(SynapseConstants.PROXY_SERVICE, name);
    //        synCtx.setTracingState(proxy.getTraceState());

    synCtx.setProperty(SynapseConstants.IS_CLIENT_DOING_REST, mc.isDoingREST());
    synCtx.setProperty(SynapseConstants.IS_CLIENT_DOING_SOAP11, mc.isSOAP11());

    try {
      if (synCtx.getEnvironment().isDebuggerEnabled()) {
        SynapseDebugManager debugManager = synCtx.getEnvironment().getSynapseDebugManager();
        debugManager.acquireMediationFlowLock();
        debugManager.advertiseMediationFlowStartPoint(synCtx);
        if (!synCtx.isResponse()) {
          SynapseWireLogHolder wireLogHolder =
              (SynapseWireLogHolder)
                  ((Axis2MessageContext) synCtx)
                      .getAxis2MessageContext()
                      .getProperty(SynapseDebugInfoHolder.SYNAPSE_WIRE_LOG_HOLDER_PROPERTY);
          if (wireLogHolder == null) {
            wireLogHolder = new SynapseWireLogHolder();
          }
          if (synCtx.getProperty(SynapseConstants.PROXY_SERVICE) != null
              && !synCtx.getProperty(SynapseConstants.PROXY_SERVICE).toString().isEmpty()) {
            wireLogHolder.setProxyName(
                synCtx.getProperty(SynapseConstants.PROXY_SERVICE).toString());
          }
          ((Axis2MessageContext) synCtx)
              .getAxis2MessageContext()
              .setProperty(SynapseDebugInfoHolder.SYNAPSE_WIRE_LOG_HOLDER_PROPERTY, wireLogHolder);
        }
      }
      synCtx.setProperty(SynapseConstants.RESPONSE_STATE, new ResponseState());
      List handlers = synCtx.getEnvironment().getSynapseHandlers();
      Iterator<SynapseHandler> iterator = handlers.iterator();
      while (iterator.hasNext()) {
        SynapseHandler handler = iterator.next();
        if (!handler.handleRequestInFlow(synCtx)) {
          return;
        }
      }

      Mediator mandatorySeq = synCtx.getConfiguration().getMandatorySequence();
      if (mandatorySeq != null) {
        if (log.isDebugEnabled()) {
          log.debug(
              "Start mediating the message in the "
                  + "pre-mediate state using the mandatory sequence");
        }

        if (!mandatorySeq.mediate(synCtx)) {
          if (log.isDebugEnabled()) {
            log.debug(
                "Request message for the proxy service "
                    + name
                    + " dropped in "
                    + "the pre-mediation state by the mandatory sequence : \n"
                    + synCtx);
          }
          return;
        }
      }

      // setup fault sequence - i.e. what happens when something goes wrong with this message
      proxy.registerFaultHandler(synCtx);

      boolean inSequenceResult = true;

      // Using inSequence for the incoming message mediation
      if (proxy.getTargetInSequence() != null) {

        Mediator inSequence = synCtx.getSequence(proxy.getTargetInSequence());
        if (inSequence != null) {
          traceOrDebug(
              traceOn,
              "Using sequence named : "
                  + proxy.getTargetInSequence()
                  + " for incoming message mediation");
          inSequenceResult = inSequence.mediate(synCtx);

        } else {
          handleException("Unable to find in-sequence : " + proxy.getTargetInSequence(), synCtx);
        }

      } else if (proxy.getTargetInLineInSequence() != null) {
        traceOrDebug(
            traceOn, "Using the anonymous " + "in-sequence of the proxy service for mediation");
        inSequenceResult = proxy.getTargetInLineInSequence().mediate(synCtx);
      }

      // if inSequence returns true, forward message to endpoint
      if (inSequenceResult) {
        if (proxy.getTargetEndpoint() != null) {
          Endpoint endpoint = synCtx.getEndpoint(proxy.getTargetEndpoint());

          if (endpoint != null) {
            traceOrDebug(
                traceOn, "Forwarding message to the endpoint : " + proxy.getTargetEndpoint());
            endpoint.send(synCtx);

          } else {
            handleException(
                "Unable to find the endpoint specified : " + proxy.getTargetEndpoint(), synCtx);
          }

        } else if (proxy.getTargetInLineEndpoint() != null) {
          traceOrDebug(
              traceOn,
              "Forwarding the message to the anonymous " + "endpoint of the proxy service");
          proxy.getTargetInLineEndpoint().send(synCtx);
        }
      }

    } catch (SynapseException syne) {

      if (!synCtx.getFaultStack().isEmpty()) {
        warn(traceOn, "Executing fault handler due to exception encountered", synCtx);
        ((FaultHandler) synCtx.getFaultStack().pop()).handleFault(synCtx, syne);

      } else {
        warn(
            traceOn,
            "Exception encountered but no fault handler found - " + "message dropped",
            synCtx);
      }
    } finally {
      // Statistic reporting
      if (isStatisticsEnabled) {
        CloseEventCollector.tryEndFlow(
            synCtx, this.name, ComponentType.PROXYSERVICE, statisticReportingIndex, true);
      }
      if (synCtx.getEnvironment().isDebuggerEnabled()) {
        SynapseDebugManager debugManager = synCtx.getEnvironment().getSynapseDebugManager();
        debugManager.advertiseMediationFlowTerminatePoint(synCtx);
        debugManager.releaseMediationFlowLock();
      }
    }
  }
  public void send(MessageContext synCtx) {

    logSetter();

    Integer statisticReportingIndex = null;
    boolean isStatisticsEnabled = RuntimeStatisticCollector.isStatisticsEnabled();
    if (isStatisticsEnabled) {
      statisticReportingIndex =
          OpenEventCollector.reportEntryEvent(
              synCtx,
              getReportingName(),
              definition.getAspectConfiguration(),
              ComponentType.ENDPOINT);
    }

    boolean traceOn = isTraceOn(synCtx);
    boolean traceOrDebugOn = isTraceOrDebugOn(traceOn);

    if (!initialized) {
      // can't send to a non-initialized endpoint. This is a program fault
      throw new IllegalStateException(
          "not initialized, " + "endpoint must be in initialized state");
    }

    prepareForEndpointStatistics(synCtx);

    if (traceOrDebugOn) {
      String address = definition.getAddress();
      if (address == null && synCtx.getTo() != null && synCtx.getTo().getAddress() != null) {
        // compute address for the default endpoint only for logging purposes
        address = synCtx.getTo().getAddress();
      }

      traceOrDebug(
          traceOn,
          "Sending message through endpoint : " + getName() + " resolving to address = " + address);
      traceOrDebug(
          traceOn,
          "SOAPAction: " + (synCtx.getSoapAction() != null ? synCtx.getSoapAction() : "null"));
      traceOrDebug(
          traceOn,
          "WSA-Action: " + (synCtx.getWSAAction() != null ? synCtx.getWSAAction() : "null"));
      if (traceOn && trace.isTraceEnabled()) {
        trace.trace("Envelope : \n" + synCtx.getEnvelope());
      }
    }

    // push the errorHandler sequence into the current message as the fault handler
    if (errorHandler != null) {
      Mediator errorHandlerMediator = synCtx.getSequence(errorHandler);
      if (errorHandlerMediator != null) {
        if (traceOrDebugOn) {
          traceOrDebug(
              traceOn,
              "Setting the onError handler : "
                  + errorHandler
                  + " for the endpoint : "
                  + endpointName);
        }
        synCtx.pushFaultHandler(new MediatorFaultHandler(errorHandlerMediator));
      } else {
        log.warn(
            "onError handler sequence : "
                + errorHandler
                + " for : "
                + endpointName
                + " cannot be found");
      }
    }

    // register this as the immediate fault handler for this message.
    synCtx.pushFaultHandler(this);
    // add this as the last endpoint to process this message - used by statistics counting code
    synCtx.setProperty(SynapseConstants.LAST_ENDPOINT, this);
    // set message level metrics collector
    org.apache.axis2.context.MessageContext axis2Ctx =
        ((Axis2MessageContext) synCtx).getAxis2MessageContext();
    axis2Ctx.setProperty(BaseConstants.METRICS_COLLECTOR, metricsMBean);

    if (contentAware) {
      try {
        RelayUtils.buildMessage(((Axis2MessageContext) synCtx).getAxis2MessageContext(), false);
        axis2Ctx.setProperty(RelayConstants.FORCE_RESPONSE_EARLY_BUILD, Boolean.TRUE);
        if (forceBuildMC) {
          ((Axis2MessageContext) synCtx).getAxis2MessageContext().getEnvelope().build();
        }
      } catch (Exception e) {
        handleException("Error while building message", e);
      }
    }

    evaluateProperties(synCtx);

    // if the envelope preserving set build the envelope
    MediatorProperty preserveEnv = getProperty(SynapseConstants.PRESERVE_ENVELOPE);
    if (preserveEnv != null
        && JavaUtils.isTrueExplicitly(
            preserveEnv.getValue() != null
                ? preserveEnv.getValue()
                : preserveEnv.getEvaluatedExpression(synCtx))) {
      if (traceOrDebugOn) {
        traceOrDebug(
            traceOn,
            "Preserving the envelope by building it before "
                + "sending, since it is explicitly set");
      }
      synCtx.getEnvelope().build();
    }

    // Send the message through this endpoint
    synCtx.getEnvironment().send(definition, synCtx);

    if (isStatisticsEnabled) {
      CloseEventCollector.closeEntryEvent(
          synCtx, getReportingName(), ComponentType.ENDPOINT, statisticReportingIndex, false);
    }
  }