package com.xeiam.xchange;

import com.xeiam.xchange.service.polling.PollingAccountService;
import com.xeiam.xchange.service.polling.PollingMarketDataService;
import com.xeiam.xchange.service.polling.PollingTradeService;
import com.xeiam.xchange.service.streaming.ExchangeStreamingConfiguration;
import com.xeiam.xchange.service.streaming.StreamingExchangeService;

/**
 * <p>
 * Abstract base class to provide the following to {@link Exchange}s:
 * </p>
 * <ul>
 * <li>Access to common methods and fields</li>
 * </ul>
 */
public abstract class BaseExchange implements Exchange {

  protected ExchangeSpecification exchangeSpecification;

  protected PollingMarketDataService pollingMarketDataService;
  protected PollingTradeService pollingTradeService;
  protected PollingAccountService pollingAccountService;
  protected StreamingExchangeService streamingExchangeService;

  @Override
  public void applySpecification(ExchangeSpecification exchangeSpecification) {

    ExchangeSpecification defaultSpecification = getDefaultExchangeSpecification();

    // Check if default is for everything
    if (exchangeSpecification == null) {
      this.exchangeSpecification = defaultSpecification;
    }
    else {
      // Using a configured exchange
      if (exchangeSpecification.getExchangeName() == null) {
        exchangeSpecification.setExchangeName(defaultSpecification.getExchangeName());
      }
      if (exchangeSpecification.getExchangeDescription() == null) {
        exchangeSpecification.setExchangeDescription(defaultSpecification.getExchangeDescription());
      }
      if (exchangeSpecification.getSslUri() == null) {
        exchangeSpecification.setSslUri(defaultSpecification.getSslUri());
      }
      if (exchangeSpecification.getHost() == null) {
        exchangeSpecification.setHost(defaultSpecification.getHost());
      }
      if (exchangeSpecification.getExchangeSpecificParameters() == null || exchangeSpecification.getExchangeSpecificParameters().size() <= 0) {
        exchangeSpecification.setExchangeSpecificParameters(defaultSpecification.getExchangeSpecificParameters());
      }
      this.exchangeSpecification = exchangeSpecification;
    }

  }

  @Override
  public ExchangeSpecification getExchangeSpecification() {

    return exchangeSpecification;
  }

  @Override
  public PollingMarketDataService getPollingMarketDataService() {

    return pollingMarketDataService;
  }

  @Override
  public PollingTradeService getPollingTradeService() {

    return pollingTradeService;
  }

  @Override
  public PollingAccountService getPollingAccountService() {

    return pollingAccountService;
  }

  @Override
  public StreamingExchangeService getStreamingExchangeService(ExchangeStreamingConfiguration configuration) {

    return streamingExchangeService;
  }

  @Override
  public String toString() {

    String name = exchangeSpecification != null ? exchangeSpecification.getExchangeName() : getClass().getName();
    return name + "#" + hashCode();
  }
}

@@ -1837,32 +1837,188 @@
 ost());%0A      %7D%0A
+      if (exchangeSpecification.getPlainTextUri() == null) %7B%0A        exchangeSpecification.setPlainTextUri(defaultSpecification.getPlainTextUri());%0A      %7D%0A
       if (exchan

Apply plaintext uri from default if not set