text:
#ifndef _PASSENGER_UNION_STATION_H_
#define _PASSENGER_UNION_STATION_H_

#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/noncopyable.hpp>
#include <oxt/thread.hpp>
#include <oxt/system_calls.hpp>
#include <oxt/backtrace.hpp>

#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#include <string>
#include <map>
#include <stdexcept>
#include <cstdio>
#include <ctime>
#include <cerrno>
#include <cassert>

#include <RandomGenerator.h>
#include <FileDescriptor.h>
#include <StaticString.h>
#include <Logging.h>
#include <Exceptions.h>
#include <Utils.h>
#include <Utils/MessageIO.h>
#include <Utils/StrIntUtils.h>
#include <Utils/MD5.h>
#include <Utils/SystemTime.h>

namespace Passenger {
namespace UnionStation {

using namespace std;
using namespace boost;
using namespace oxt;

// All access to the file descriptor must be synchronized through the lock.
struct Connection {
	mutable boost::mutex syncher;
	int fd;

	Connection(int _fd)
		: fd(_fd)
		{ }

	~Connection() {
		disconnect();
	}

	bool connected() const {
		return fd != -1;
	}

	bool disconnect(string &errorResponse) {
		if (!connected()) {
			return false;
		}

		/* The server might send an "error" array message
		 * just before disconnecting. Try to read it.
		 */
		TRACE_POINT();
		vector<string> response;
		try {
			unsigned long long timeout = 20000000;
			while (true) {
				response = readArrayMessage(fd, &timeout);
			}
		} catch (const TimeoutException &) {
			/* This means that the last message isn't an array
			 * message or that the server didn't send it quickly
			 * enough. In any case, discard whatever previous
			 * array messages we were able to read because they're
			 * guaranteed not to be the error message we're expecting.
			 */
			response.clear();
		} catch (const SystemException &e) {
			/* We treat ECONNRESET the same as EOFException.
			 * Other errors are treated as TimeoutException.
			 */
			if (e.code() != ECONNRESET) {
				response.clear();
			}
		} catch (const EOFException &) {
			/* Do nothing. We've successfully read the last array message. */
		}

		UPDATE_TRACE_POINT();
		disconnect();

		if (response.size() == 2 && response[0] == "error") {
			errorResponse = response[1];
			return true;
		} else {
			return false;
		}
	}

	void disconnect() {
		if (fd != -1) {
			this_thread::disable_interruption di;
			this_thread::disable_syscall_interruption dsi;
			safelyClose(fd);
			fd = -1;
		}
	}
};

typedef shared_ptr<Connection> ConnectionPtr;

/** A special lock type for Connection that also keeps a smart
 * pointer to the data structure so that the mutex is not destroyed
 * prematurely.
 */
struct ConnectionLock {
	ConnectionPtr connection;
	bool locked;

	ConnectionLock(const ConnectionPtr &c)
		: connection(c)
	{
		c->syncher.lock();
		locked = true;
	}

	~ConnectionLock() {
		if (locked) {
			connection->syncher.unlock();
		}
	}

	void reset(const ConnectionPtr &c, bool lockNow = true) {
		if (locked) {
			connection->syncher.unlock();
		}
		connection = c;
		if (lockNow) {
			connection->syncher.lock();
			locked = true;
		} else {
			locked = false;
		}
	}

	void lock() {
		assert(!locked);
		connection->syncher.lock();
		locked = true;
	}
};

/**
 * A scope guard which closes the given Connection on destruction unless cleared.
 */
class ConnectionGuard {
private:
	ConnectionPtr connection;
	bool cleared;

public:
	ConnectionGuard(const ConnectionPtr &_connection)
		: connection(_connection),
		  cleared(false)
		{ }

	~ConnectionGuard() {
		if (!cleared) {
			connection->disconnect();
		}
	}

	void clear() {
		cleared = true;
	}
};

enum ExceptionHandlingMode {
	PRINT,
	THROW,
	IGNORE
};

class LoggerFactory;
typedef shared_ptr<LoggerFactory> LoggerFactoryPtr;

inline void _checkinConnection(const LoggerFactoryPtr &loggerFactory, const ConnectionPtr &connection);

class Logger: public boost::noncopyable {
private:
	static const int INT64_STR_BUFSIZE = 22; // Long enough for a 64-bit number.
	static const unsigned long long IO_TIMEOUT = 5000000; // In microseconds.

	const LoggerFactoryPtr loggerFactory;
	const ConnectionPtr connection;
	const string txnId;
	const string groupName;
	const string category;
	const string unionStationKey;
	const ExceptionHandlingMode exceptionHandlingMode;
	bool shouldFlushToDiskAfterClose;

	/**
	 * Buffer must be at least txnId.size() + 1 + INT64_STR_BUFSIZE + 1 bytes.
	 */
	char *insertTxnIdAndTimestamp(char *buffer, const char *end) {
		assert(end - buffer >= int(txnId.size() + 1 + INT64_STR_BUFSIZE + 1));
		int size;

		// "txn-id-here"
		buffer = appendData(buffer, end, txnId);

		// "txn-id-here "
		buffer = appendData(buffer, end, " ", 1);

		// "txn-id-here 123456"
		assert(end - buffer >= INT64_STR_BUFSIZE);
		size = snprintf(buffer, INT64_STR_BUFSIZE, "%llu", SystemTime::getUsec());
		if (size >= INT64_STR_BUFSIZE) {
			// The buffer is too small.
			throw IOException("Cannot format a new transaction log message timestamp.");
		}
		buffer += size;

		// "txn-id-here 123456 "
		buffer = appendData(buffer, end, " ", 1);

		return buffer;
	}

	template<typename ExceptionType>
	void handleException(const ExceptionType &e) {
		switch (exceptionHandlingMode) {
		case THROW:
			throw e;
		case PRINT:
			try {
				const tracable_exception &te =
					dynamic_cast<const tracable_exception &>(e);
				P_WARN(te.what() << "\n" << te.backtrace());
			} catch (const bad_cast &) {
				P_WARN(e.what());
			}
			break;
		default:
			break;
		}
	}

public:
	Logger()
		: exceptionHandlingMode(PRINT)
		{ }

	Logger(const LoggerFactoryPtr &_loggerFactory,
		const ConnectionPtr &_connection,
		const string &_txnId,
		const string &_groupName,
		const string &_category,
		const string &_unionStationKey,
		ExceptionHandlingMode _exceptionHandlingMode = PRINT)
		: loggerFactory(_loggerFactory),
		  connection(_connection),
		  txnId(_txnId),
		  groupName(_groupName),
		  category(_category),
		  unionStationKey(_unionStationKey),
		  exceptionHandlingMode(_exceptionHandlingMode),
		  shouldFlushToDiskAfterClose(false)
		{ }

	~Logger() {
		TRACE_POINT();
		if (connection == NULL) {
			return;
		}
		ConnectionLock l(connection);
		if (!connection->connected()) {
			return;
		}

		char timestamp[2 * sizeof(unsigned long long) + 1];
		integerToHexatri<unsigned long long>(SystemTime::getUsec(),
			timestamp);

		UPDATE_TRACE_POINT();
		ConnectionGuard guard(connection);
		try {
			unsigned long long timeout = IO_TIMEOUT;
			writeArrayMessage(connection->fd, &timeout,
				"closeTransaction",
				txnId.c_str(),
				timestamp,
				NULL);

			if (shouldFlushToDiskAfterClose) {
				UPDATE_TRACE_POINT();
				timeout = IO_TIMEOUT;
				writeArrayMessage(connection->fd, &timeout,
					"flush", NULL);
				readArrayMessage(connection->fd, &timeout);
			}

			_checkinConnection(loggerFactory, connection);
			guard.clear();
		} catch (const SystemException &e) {
			string errorResponse;

			UPDATE_TRACE_POINT();
			guard.clear();
			if (connection->disconnect(errorResponse)) {
				handleException(IOException(
					"Logging agent disconnected with error: " +
					errorResponse));
			} else {
				handleException(e);
			}
		}
	}

	void message(const StaticString &text) {
		TRACE_POINT();
		if (connection == NULL) {
			P_TRACE(3, "[Union Station log to null] " << text);
			return;
		}
		ConnectionLock l(connection);
		if (!connection->connected()) {
			P_TRACE(3, "[Union Station log to null] " << text);
			return;
		}

		char timestamp[2 * sizeof(unsigned long long) + 1];
		integerToHexatri<unsigned long long>(SystemTime::getUsec(), timestamp);

		UPDATE_TRACE_POINT();
		ConnectionGuard guard(connection);
		try {
			unsigned long long timeout = IO_TIMEOUT;
			P_TRACE(3, "[Union Station log] " << txnId << " " << timestamp << " " << text);
			writeArrayMessage(connection->fd, &timeout,
				"log",
				txnId.c_str(),
				timestamp,
				NULL);
			writeScalarMessage(connection->fd, text, &timeout);
			guard.clear();
		} catch (const std::exception &e) {
			string errorResponse;

			UPDATE_TRACE_POINT();
			guard.clear();
			if (connection->disconnect(errorResponse)) {
				handleException(IOException(
					"Logging agent disconnected with error: " +
					errorResponse));
			} else {
				handleException(e);
			}
		}
	}

	void abort(const StaticString &text) {
		message("ABORT");
	}

	void flushToDiskAfterClose(bool value) {
		shouldFlushToDiskAfterClose = value;
	}

	bool isNull() const {
		return connection == NULL;
	}

	const string &getTxnId() const {
		return txnId;
	}

	const string &getGroupName() const {
		return groupName;
	}

	const string &getCategory() const {
		return category;
	}

	const string &getUnionStationKey() const {
		return unionStationKey;
	}
};

typedef shared_ptr<Logger> LoggerPtr;

class ScopeLog: public noncopyable {
private:
	Logger * const log;
	enum {
		NAME,
		GRANULAR
	} type;
	union {
		const char *name;
		struct {
			const char *endMessage;
			const char *abortMessage;
		} granular;
	} data;
	bool ok;

	static string timevalToString(struct timeval &tv) {
		unsigned long long i = (unsigned long long) tv.tv_sec * 1000000 + tv.tv_usec;
		return usecToString(i);
	}

	static string usecToString(unsigned long long usec) {
		char timestamp[2 * sizeof(unsigned long long) + 1];
		integerToHexatri<unsigned long long>(usec, timestamp);
		return timestamp;
	}

public:
	ScopeLog()
		: log(NULL)
		{ }

	ScopeLog(const LoggerPtr &_log, const char *name)
		: log(_log.get())
	{
		type = NAME;
		data.name = name;
		ok = false;

		char message[150];
		char *pos = message;
		const char *end = message + sizeof(message);
		struct rusage usage;

		pos = appendData(pos, end, "BEGIN: ");
		pos = appendData(pos, end, name);
		pos = appendData(pos, end, " (");
		pos = appendData(pos, end, usecToString(SystemTime::getUsec()));
		pos = appendData(pos, end, ",");
		if (getrusage(RUSAGE_SELF, &usage) == -1) {
			int e = errno;
			throw SystemException("getrusage() failed", e);
		}
		pos = appendData(pos, end, timevalToString(usage.ru_utime));
		pos = appendData(pos, end, ",");
		pos = appendData(pos, end, timevalToString(usage.ru_stime));
		pos = appendData(pos, end, ") ");

		if (log != NULL) {
			log->message(StaticString(message, pos - message));
		}
	}

	ScopeLog(const LoggerPtr &_log,
		const char *beginMessage,
		const char *endMessage,
		const char *abortMessage = NULL)
		: log(_log.get())
	{
		if (_log != NULL) {
			type = GRANULAR;
			data.granular.endMessage = endMessage;
			data.granular.abortMessage = abortMessage;
			ok = abortMessage == NULL;
			_log->message(beginMessage);
		}
	}

	~ScopeLog() {
		if (log == NULL) {
			return;
		}
		if (type == NAME) {
			char message[150];
			char *pos = message;
			const char *end = message + sizeof(message);
			struct rusage usage;

			if (ok) {
				pos = appendData(pos, end, "END: ");
			} else {
				pos = appendData(pos, end, "FAIL: ");
			}
			pos = appendData(pos, end, data.name);
			pos = appendData(pos, end, " (");
			pos = appendData(pos, end, usecToString(SystemTime::getUsec()));
			pos = appendData(pos, end, ",");
			if (getrusage(RUSAGE_SELF, &usage) == -1) {
				int e = errno;
				throw SystemException("getrusage() failed", e);
			}
			pos = appendData(pos, end, timevalToString(usage.ru_utime));
			pos = appendData(pos, end, ",");
			pos = appendData(pos, end, timevalToString(usage.ru_stime));
			pos = appendData(pos, end, ")");

			log->message(StaticString(message, pos - message));
		} else {
			if (ok) {
				log->message(data.granular.endMessage);
			} else {
				log->message(data.granular.abortMessage);
			}
		}
	}

	void success() {
		ok = true;
	}
};

class LoggerFactory: public enable_shared_from_this<LoggerFactory> {
private:
	static const unsigned int CONNECTION_POOL_MAX_SIZE = 10;

	const string serverAddress;
	const string username;
	const string password;
	const string nodeName;
	RandomGenerator randomGenerator;

	LoggerPtr nullLogger;

	/** Lock protecting the fields that follow, but not the
	 * contents of the connection object.
	 */
	mutable boost::mutex syncher;
	vector<ConnectionPtr> connectionPool;
	unsigned int maxConnectTries;
	unsigned long long reconnectTimeout;
	unsigned long long nextReconnectTime;

	static string determineNodeName(const string &givenNodeName) {
		if (givenNodeName.empty()) {
			return getHostName();
		} else {
			return givenNodeName;
		}
	}

	static bool isNetworkError(int code) {
		return code == EPIPE || code == ECONNREFUSED || code == ECONNRESET
			|| code == EHOSTUNREACH || code == ENETDOWN || code == ENETUNREACH
			|| code == ETIMEDOUT;
	}

	template<typename T>
	static bool instanceof(const std::exception &e) {
		try {
			(void) dynamic_cast<const T &>(e);
			return true;
		} catch (const bad_cast &) {
			return false;
		}
	}

	ConnectionPtr createNewConnection() {
		TRACE_POINT();
		int fd;
		vector<string> args;
		unsigned long long timeout = 15000000;

		fd = connectToServer(serverAddress);
		FdGuard guard(fd, true);
		if (!readArrayMessage(fd, args, &timeout)) {
			throw IOException("The logging agent closed the connection before sending a version identifier.");
		}
		if (args.size() != 2 || args[0] != "version") {
			throw IOException("The logging agent server didn't sent a valid version identifier.");
		}
		if (args[1] != "1") {
			string message = "Unsupported logging agent protocol version " +
				args[1] + ".";
			throw IOException(message);
		}

		UPDATE_TRACE_POINT();
		writeScalarMessage(fd, username, &timeout);
		writeScalarMessage(fd, password, &timeout);

		UPDATE_TRACE_POINT();
		if (!readArrayMessage(fd, args, &timeout)) {
			throw IOException("The logging agent did not send an authentication response.");
		} else if (args.size() != 1) {
			throw IOException("The authentication response that the logging agent sent is not valid.");
		} else if (args[0] != "ok") {
			throw SecurityException("The logging agent server denied authentication: " + args[0]);
		}

		UPDATE_TRACE_POINT();
		writeArrayMessage(fd, &timeout, "init", nodeName.c_str(), NULL);
		if (!readArrayMessage(fd, args, &timeout)) {
			throw SystemException("Cannot connect to logging server", ECONNREFUSED);
		} else if (args.size() != 1) {
			throw IOException("Logging server returned an invalid reply for the 'init' command");
		} else if (args[0] == "server shutting down") {
			throw SystemException("Cannot connect to server", ECONNREFUSED);
		} else if (args[0] != "ok") {
			throw IOException("Logging server returned an invalid reply for the 'init' command");
		}

		guard.clear();
		return make_shared<Connection>(fd);
	}

public:
	LoggerFactory() {
		nullLogger = make_shared<Logger>();
	}

	LoggerFactory(const string &_serverAddress, const string &_username,
	              const string &_password, const string &_nodeName = string())
		: serverAddress(_serverAddress),
		  username(_username),
		  password(_password),
		  nodeName(determineNodeName(_nodeName))
	{
		nullLogger = make_shared<Logger>();
		if (!_serverAddress.empty() && isLocalSocketAddress(_serverAddress)) {
			maxConnectTries = 10;
		} else {
			maxConnectTries = 1;
		}
		reconnectTimeout  = 1000000;
		nextReconnectTime = 0;
	}

	ConnectionPtr checkoutConnection() {
		TRACE_POINT();
		unique_lock<boost::mutex> l(syncher);
		if (!connectionPool.empty()) {
			P_TRACE(3, "Checked out existing connection");
			ConnectionPtr connection = connectionPool.back();
			connectionPool.pop_back();
			return connection;

		} else {
			if (SystemTime::getUsec() < nextReconnectTime) {
				P_TRACE(3, "Not yet time to reconnect; returning NULL connection");
				return ConnectionPtr();
			}

			l.unlock();
			P_TRACE(3, "Creating new connection with logging agent");
			ConnectionPtr connection;
			try {
				connection = createNewConnection();
			} catch (const TimeoutException &) {
				l.lock();
				P_WARN("Timeout trying to connect to the logging agent at " << serverAddress << "; " <<
					"will reconnect in " << reconnectTimeout / 1000000 << " second(s).");
				nextReconnectTime = SystemTime::getUsec() + reconnectTimeout;
				return ConnectionPtr();
			} catch (const tracable_exception &e) {
				l.lock();
				nextReconnectTime = SystemTime::getUsec() + reconnectTimeout;
				if (instanceof<IOException>(e) || instanceof<SystemException>(e)) {
					P_WARN("Cannot connect to the logging agent at " << serverAddress <<
						" (" << e.what() << "); will reconnect in " <<
						reconnectTimeout / 1000000 << " second(s).");
					return ConnectionPtr();
				} else {
					throw;
				}
			}

			return connection;
		}
	}

	void checkinConnection(const ConnectionPtr &connection) {
		lock_guard<boost::mutex> l(syncher);
		if (connectionPool.size() < CONNECTION_POOL_MAX_SIZE) {
			connectionPool.push_back(connection);
		} else {
			connection->disconnect();
		}
	}

	LoggerPtr createNullLogger() const {
		return nullLogger;
	}

	LoggerPtr newTransaction(const string &groupName,
		const string &category = "requests",
		const string &unionStationKey = string(),
		const string &filters = string())
	{
		if (serverAddress.empty()) {
			return createNullLogger();
		}

		unsigned long long timestamp = SystemTime::getUsec();
		char txnId[
			2 * sizeof(unsigned int) +    // max hex timestamp size
			11 +                          // space for a random identifier
			1                             // null terminator
		];
		char *end;
		unsigned int timestampSize;
		char timestampStr[2 * sizeof(unsigned long long) + 1];

		// "[timestamp]"
		// Our timestamp is like a Unix timestamp but with minutes
		// resolution instead of seconds. 32 bits will last us for
		// about 8000 years.
		timestampSize = integerToHexatri<unsigned int>(timestamp / 1000000 / 60,
			txnId);
		end = txnId + timestampSize;

		// "[timestamp]-"
		*end = '-';
		end++;

		// "[timestamp]-[random id]"
		randomGenerator.generateAsciiString(end, 11);
		end += 11;
		*end = '\0';

		integerToHexatri<unsigned long long>(timestamp, timestampStr);

		ConnectionPtr connection = checkoutConnection();
		if (connection == NULL) {
			return createNullLogger();
		}

		ConnectionLock cl(connection);
		ConnectionGuard guard(connection);

		try {
			unsigned long long timeout = 15000000;

			writeArrayMessage(connection->fd, &timeout,
				"openTransaction",
				txnId,
				groupName.c_str(),
				"",
				category.c_str(),
				timestampStr,
				unionStationKey.c_str(),
				"true",
				"true",
				filters.c_str(),
				NULL);

			vector<string> args;
			if (!readArrayMessage(connection->fd, args, &timeout)) {
				lock_guard<boost::mutex> l(syncher);
				P_WARN("The logging agent at " << serverAddress <<
					" closed the connection (no error message given);" <<
					" will reconnect in " << reconnectTimeout / 1000000 <<
					" second(s).");
				nextReconnectTime = SystemTime::getUsec() + reconnectTimeout;
				return createNullLogger();
			} else if (args.size() == 2 && args[0] == "error") {
				lock_guard<boost::mutex> l(syncher);
				P_WARN("The logging agent at " << serverAddress <<
					" closed the connection (error message: " << args[1] <<
					"); will reconnect in " << reconnectTimeout / 1000000 <<
					" second(s).");
				nextReconnectTime = SystemTime::getUsec() + reconnectTimeout;
				return createNullLogger();
			} else if (args.empty() || args[0] != "ok") {
				lock_guard<boost::mutex> l(syncher);
				P_WARN("The logging agent at " << serverAddress <<
					" sent an unexpected reply;" <<
					" will reconnect in " << reconnectTimeout / 1000000 <<
					" second(s).");
				nextReconnectTime = SystemTime::getUsec() + reconnectTimeout;
				return createNullLogger();
			}

			guard.clear();
			return make_shared<Logger>(shared_from_this(),
				connection,
				string(txnId, end - txnId),
				groupName, category,
				unionStationKey);

		} catch (const TimeoutException &) {
			lock_guard<boost::mutex> l(syncher);
			P_WARN("Timeout trying to communicate with the logging agent at " << serverAddress << "; " <<
				"will reconnect in " << reconnectTimeout / 1000000 << " second(s).");
			nextReconnectTime = SystemTime::getUsec() + reconnectTimeout;
			return createNullLogger();

		} catch (const SystemException &e) {
			if (e.code() == ENOENT || isNetworkError(e.code())) {
				string errorResponse;
				bool gotErrorResponse;

				guard.clear();
				gotErrorResponse = connection->disconnect(errorResponse);
				lock_guard<boost::mutex> l(syncher);
				if (gotErrorResponse) {
					P_WARN("The logging agent at " << serverAddress <<
						" closed the connection (error message: " << errorResponse <<
						"); will reconnect in " << reconnectTimeout / 1000000 <<
						" second(s).");
				} else {
					P_WARN("The logging agent at " << serverAddress <<
						" closed the connection (no error message given);" <<
						" will reconnect in " << reconnectTimeout / 1000000 <<
						" second(s).");
				}
				nextReconnectTime = SystemTime::getUsec() + reconnectTimeout;
				return createNullLogger();
			} else {
				throw;
			}
		}
	}

	LoggerPtr continueTransaction(const string &txnId,
		const string &groupName,
		const string &category = "requests",
		const string &unionStationKey = string())
	{
		if (serverAddress.empty() || txnId.empty()) {
			return createNullLogger();
		}

		char timestampStr[2 * sizeof(unsigned long long) + 1];
		integerToHexatri<unsigned long long>(SystemTime::getUsec(), timestampStr);

		ConnectionPtr connection = checkoutConnection();
		if (connection == NULL) {
			return createNullLogger();
		}

		ConnectionLock cl(connection);
		ConnectionGuard guard(connection);

		try {
			unsigned long long timeout = 15000000;
			writeArrayMessage(connection->fd, &timeout,
				"openTransaction",
				txnId.c_str(),
				groupName.c_str(),
				"",
				category.c_str(),
				timestampStr,
				unionStationKey.c_str(),
				"true",
				NULL);
			guard.clear();
			return make_shared<Logger>(shared_from_this(),
				connection,
				txnId, groupName, category,
				unionStationKey);

		} catch (const TimeoutException &) {
			lock_guard<boost::mutex> l(syncher);
			P_WARN("Timeout trying to communicate with the logging agent at " << serverAddress << "; " <<
				"will reconnect in " << reconnectTimeout / 1000000 << " second(s).");
			nextReconnectTime = SystemTime::getUsec() + reconnectTimeout;
			return createNullLogger();

		} catch (const SystemException &e) {
			if (e.code() == ENOENT || isNetworkError(e.code())) {
				string errorResponse;
				bool gotErrorResponse;

				guard.clear();
				gotErrorResponse = connection->disconnect(errorResponse);
				lock_guard<boost::mutex> l(syncher);
				if (gotErrorResponse) {
					P_WARN("The logging agent at " << serverAddress <<
						" closed the connection (error message: " << errorResponse <<
						"); will reconnect in " << reconnectTimeout / 1000000 <<
						" second(s).");
				} else {
					P_WARN("The logging agent at " << serverAddress <<
						" closed the connection (no error message given);" <<
						" will reconnect in " << reconnectTimeout / 1000000 <<
						" second(s).");
				}
				nextReconnectTime = SystemTime::getUsec() + reconnectTimeout;
				return createNullLogger();
			} else {
				throw;
			}
		}
	}

	void setMaxConnectTries(unsigned int value) {
		lock_guard<boost::mutex> l(syncher);
		maxConnectTries = value;
	}

	void setReconnectTimeout(unsigned long long usec) {
		lock_guard<boost::mutex> l(syncher);
		reconnectTimeout = usec;
	}

	bool isNull() const {
		return serverAddress.empty();
	}

	const string &getAddress() const {
		return serverAddress;
	}

	const string &getUsername() const {
		return username;
	}

	const string &getPassword() const {
		return password;
	}

	/**
	 * @post !result.empty()
	 */
	const string &getNodeName() const {
		return nodeName;
	}
};

inline void
_checkinConnection(const LoggerFactoryPtr &loggerFactory, const ConnectionPtr &connection) {
	loggerFactory->checkinConnection(connection);
}

} // namespace UnionStation
} // namespace Passenger

#endif /* _PASSENGER_UNION_STATION_H_ */


text:
Skype for Business Features Released to Broader Preview
Microsoft on Wednesday broadened the testing pool of some new Skype for Business features and announced some additions.
Microsoft rolled out previews of three Skype for Business features in July that required having Office 365 subscriptions to either the Enterprise plan or the Skype for Business Plan 2. However, some of those previews were limited back then with regard to country participation and languages supported.
Expanded Previews
One of the expanded features is called "Cloud PBX with PSTN Calling." It's a PBX replacement cloud solution designed to permit traditional phone calls -- that is, calls made via the public switched telephone network (PSTN) -- to be made and received using the Skype for Business client. This preview was previously only available in the United States, but it now can be tested by organizations using Skype for Business Server worldwide in conjunction with an Office 365 subscription. Microsoft's announcement Wednesday noted that having Skype for Business Server on-premises currently is a requirement to use this feature, "but we plan to provide additional options over time." The new Cloud PBX with PSTN Calling feature is expected to hit commercial release worldwide "before the end of this year," according to the announcement.
Microsoft's phone hardware partners have already built some IP phones with support for the Cloud PBX with PSTN Calling feature. It's currently supported in the following phones if they have updated firmware: Polycom CX600, CX3000 and VVX models, the HP 4120 phone, and the Mitel Mivoice 6725 phone. New phone support will be arriving "over the next several months," Microsoft promised.
Another expanded preview is the "PSTN Conferencing" feature for Skype for Business Online, which is Microsoft's cloud version of the product. This PSTN Conferencing feature, which lets people connect to conferences via landline or mobile phones, previously had just been limited to the U.S. market. However, it's now available this month for testing in "Belgium, Canada, Denmark, France, Germany, Italy, Netherlands, Spain, Sweden, Switzerland and the United Kingdom." Next month, it'll be available for testing in "Finland, Norway and South Africa." It'll be available commercially in all of those markets "before the end of this year," Microsoft indicated.
Additional Feature Previews
Microsoft added some other preview features to Skype for Business. Its Cloud PBX with PSTN Calling preview feature is getting "number portability," meaning that an organization's existing phone numbers can be used with it. However, that's just being enabled in the U.S. market at present in the preview.
The Cloud PBX with PSTN Calling preview also is getting a "voicemail" capability worldwide. Microsoft's announcement was unclear if the number portability and voicemail additions could be tested now, though.
A new Call Quality Dashboard feature will be added to Skype for Business "later this month," according to Microsoft. This dashboard shows "aggregated quality information for both meetings and calls." IT pros will be able to check call volumes in both daily and monthly views. Call quality can be compared against user location, as well as the "IP network type."
Microsoft's unified communications products include both Skype for Business Server 2015, which was released in May, and its Office 365 offering called "Skype for Business Online." Organizations are typically using the server products now, but Microsoft has been ratcheting up its online product capabilities, with voice improvements expected around year's end. For a discussion along those lines, see this Q&A article with a Microsoft partner.
The preceding server product is called Lync Server 2013. Microsoft is promising that organizations just need to perform an in-place upgrade of Lync Server 2013 to move to Skype for Business Server 2015. Organizations running Lync Server 2010, though, have to follow the old wipe-and-replace approach. For a discussion about those upgrade options, see this recent Microsoft blog post by Skype for Business MVP, Dino Caputo.

redpajama_set_name: RedPajamaCommonCrawl


Video Mailbag: Will the Jets miss running back Chris Ivory?
For the third-straight week, Jets Wire hosted a LIVE question-and-answer mailbag over on our Facebook page where we tried to ease your mind on any of your worries pertaining to the Jets.
Prior to the event, we compiled a few questions via Twitter submission, answered them via video, then took a few more that were dropped in the comment section during the broadcast.
A little sampling of what was asked? Does Tom Hackett have a chance of beating out Lac Edwards, is Matt Forte an improvement over Chris Ivory, should there be concern that Darron Lee isn't signed yet, and much, much more.
1:10– Is there a chance Tom Hackett beats out Lac Edwards for the Jets punting job?
2:15– What is the percentage chance Christian Hackenberg will be a middle of the round QB, or better?
6:38– Who's the next Jet that will get a big contract?
8:18– Can you compare Bryce Petty in 2015, with Christian Hackenberg in 2016?
10:45– Is there any concern Darron Lee isn't signed yet?
12:18– Will Jets miss Chris Ivory, or does Matt Forte fill the void?
14:36– Should Jets fans be concerned with Darrelle Revis injury, and secondary status with him out?
17:15– Is it better to have a directional kicker, or power kicker?
You'll now receive the top Jets Wire stories each day directly in your inbox.
What are the Jets biggest needs with the NFL draft approaching?
This site is neither endorsed, nor sponsored by, nor affiliated with New York Jets or NFL Properties LLC. Jets is a registered trademark of the New York Jets LLC.


Are you frustrated with the medical system?
Do you believe it is too expensive and often does more harm than good?
Would you like to start taking your health into your own hands, like your grandparents and all your other ancestors did?
If so, I have great news!
My good friend, Marjory Wildcraft, is offering a free, 4-part video series to help you transform from relying on drugstores and doctors, to becoming your own Medicine Woman or Medicine Man.
Register for the whole inspiring series here.
To start you on the path toward making your own medicine, so you can confidently heal the 12 most common ailments that any family deals with.
In the first video, Marjory discusses the 3 major reasons why you should AVOID the existing medical system(especially pay attention to the section where she talks about the problems with medical mistakes – that's scary…).
And that's just Part 1!
Every 1 of the 4 videos is PACKED with useful, life-changing, empowering wisdom.
But you do have to act now because this series is only available for a few days!
Watch it all here. I think you'll be glad you did.
Weeds That Promote Hair Growth? Dandelions & All Things Hair!


One of my favourite blogs would have to be sugar*sugar and every Sunday she and a number of other bloggers decide on a new topic for Show and Tell Sunday. Today's topic is beautiful china, silver and crystal, last weeks was vintage linens. It has peeked my interest and so I've decided to join in!
I managed to find it at a small table at a local craft market, the seller said he got it from an estate sale. There were more cups to the set, but I had a limit to what I wanted to spend and with so many other bargains to be had I decided one cup and saucer was enough. I love how delicate the little blue flowers are.
You made me curious to your other china! The one you showed us is absolutely pretty!
Love the pattern and the color!! Thanks for sharing.
Such a pretty little cup and saucer! Thanks for sharing today!
Thanks so much for sharing your favorite china. Such a lovely cup & saucer!!
I like how delicate your little blue flowered teacup is. Restraint is a tough thing when beauty and bargains are combined!!
What a pretty cup and saucer. Those blue flowers are just beautiful. Enjoy drinking tea out of it!
I have a love for tea pots. There are just so many dif. kinds out there.


The concept of a project can be offered as a series of jobs which resulted in conclusion of a more impressive piece of content. Which means you'll want to take time to do-all of the smaller tasks including feasible, and preparing all of them is a huge element of this.
The starting place for tasks are the task routine. This is what lets you know what you're working towards so when you need to achieve it by. Knowing your milestones then chances are you have actually a much better possibility of following all of them.
If you look at the set of activities to do and realize it is too big for you personally it is time for you to get other individuals involved. A, flexible task group is worth its body weight in gold in helping use the load down your shoulders. You need ton't be afraid to allow get and let others help.
What lengths ahead you ought to prepare probably is determined by how complex the task is and just how forced you will be for time. In terms of step-by-step planning I like to look weekly ahead. I feel that in the event that you try to plan further ahead than this you will have to develop in many contingency as unanticipated situations are certain to occur for the time being.
Making plans for your jobs on a bit of report is okay but today you will have much more modern-day resources open to you therefore you should use them. In your early days into the role you really need to make the most and find out about the tools you should use so that you tend to be more comfortable with all of them once the minute concerns use them in earnest.
One of the most important areas of great preparation is you can find out what problems face you in the future. This means using a bit of time and energy to look at the jobs and question just what dilemmas it might involve. Doing this means you'll exercise more accurately just how long it could take one to solve every one.
Really i enjoy policy for the next day before I-go residence. I am going to have my a number of once a week jobs which I can undergo and amend. Something that has be or less immediate during the day may be changed accordingly before we leave the office. It has two benefits. To begin with, I don't have any irritating doubts during my mind as I go homeward; I'm sure just what requires done the next day. Subsequently, I am able to get-off to a flying begin the following day.
Perchance you hate preparing but there is no genuine reason to feel just like this. Its an integral part of the project supervisor part which may be fairly enjoyable should you choose it right. When I simply mentioned, I like carrying it out at the conclusion of the day and also this provides me personally an opportunity to wind down going back 5 or ten full minutes associated with working-day. Seeing your to-do number have shorter can be a good incentive for carrying this out the correct way.
To plan successfully it is important to clear the head of a few of the issues and complications which are swirling around inside it. This may suggest planning to a quiet an element of the office or waiting until everyone went residence. I've constantly found the employees restaurant good destination to get and prepare if it is empty.
You can easily go through the listing of things you can do and cherry select the effortless ones very first. That isn't a great long haul method. You have to be honest and choose those which are most immediate no matter whether you want to do all of them or perhaps not. They'll need done eventually therefore it might as well be now versus once they become really urgent.


You've grown the neighborhood's best-looking petunias. Now you want to capture the moment with a stylish picture. But all of your attempts don't seem to do your garden justice. To help you get the most from your camera, The Wave Team asked its resident photographer Mark for some tips. You'll be happy with the level of professionalism these simple steps add to your photography!


To assist in the Healing Process of others, we must first heal ourselves.
Strengthen their practice of T.T.
Through Therapeutic Touch practice, development and exchange you will strengthen your skills as a T.T. practitioner and expand your personal awareness of this healing art form.
Through an in-depth study of the chakras and their physical, emotional, mental and spiritual aspects (C. Myss, B. Brennan and others) and applying them to the self, you will have the opportunity to experience a deeper connection and understanding of your inner life and areas of personal strengths and challenge. Deep Healing, Growth and Enhanced Wellbeing can be facilitated by working at this level.
Through classroom work and assignments such as: Aligning With Your Truth, Interpersonal Relationships and The Face in the Mirror, you will gain a fuller appreciation of your True Self and Life Goals and have opportunity to create a personal working plan to develop these.
Creative imagery and Visualization techniques will be explored and developed.
Meditation Practice, Centering, Relaxation and Focusing techniques shown to enhance the practice of T.T. will be explored.
T.T. Levels 1, 2 and 3 are available through this program with a focus on areas requested by participants. These may count as repeat levels.
The opportunity to fulfill case study requirements while working towards the T.T.N.O. Recognized Practitioner Status; the T.T.N.O. Workbook is used.
A Healing Sweat Lodge Ceremony and Retreat is offered as part of this course.
This T.T.N. (O) approved Therapeutic Touch Year Long Program is offered once a month. The course may be taken in either Toronto (905) 457-8416 or Simcoe (519) 426-5873. Prerequisite: Level Three (or intention to complete during course).
The Healing the Healer Program is being offered to Therapeutic Touch Practitioners who wish to, explore T.T. at an advanced and in-depth level. The best way to do this is through self examination, reflection and alignment with your true self.
I often use the analogy of the onion when explaining what this type of work is about. All of us are like onions - we are multi layered. It is through the peeling away of these layers - which sometimes bring tears of all kinds - that we can reach the core, the essence of who we really are. Then, and only then, are we able to truly assist in the healing of others.
Without this type of work, intuition is always suspect. We ask, "Are my instincts right about this, or am I projecting 'my stuff'"? Without this type of work we are not sufficiently healed ourselves and therefore look at the world - relationships and people who reach out to us for assistance - through all that we still need to address in ourselves; the view is never 'clear'. There is a You inside of you who knows . . . who's insights and intuition are sure and readily available. A You that moves into life from a place of clarity and confidence. This program will give you the tools you need to reach that part of yourself! You will expand your levels of awareness, which will be an invaluable assistance to you as an individual, a parent, a friend, a partner and as a Therapeutic Touch practitioner.
This is a program I love to facilitate. I see so much positive change in people and so much growth. I see their abilities as a 'healer' expand and develop . . . and I learn so very much myself though interaction with all the people who involve themselves with this program.
Throughout my twelve years experience as a Holistic Therapist, working with a variety of modalities - Therapeutic Touch, Massage, Shiatsu, CranioSacral and various forms of intuitive work - whether in a clinical practice with accident rehab or physically challenged children and their families, or as a counsellor - for me it always comes down to one thing; everyone needs to find and connect with their own true essence.
I hope you will take this opportunity to try this experience for yourself.
Click here for next scheduled course.


a business or management related course.
We also welcome students with relevant professional practice experience should they not hold a higher education qualification.
For those students without professional experience in museums and galleries, voluntary museum work is not a requirement for acceptance on the course.
Through this course you will acquire real-world experience of working in museums and galleries. Our imaginative, interdisciplinary, international approach advances your knowledge of contemporary developments in this vibrant and sophisticated area of culture, arts and heritage. Employment destinations of our previous students have included the Natural History Museum, V&A, Museum of London and the National Gallery.
We provide you with transferable skills essential across the sector, working with museum and gallery professionals to nationally and internationally recognised standards.
Research opportunities inside museums and galleries allows you to develop your own interests and gain valuable research and practice-based skills.


You send your disks – we send you results!
Do USB Floppy Drives Work? Can I do this Myself?
How will I receive my results?
Can I back up to the Cloud?
Will an old PC program run on my Mac?
What if you can't read my disks?
We guide you through the mists of time, recovering information you thought was missing or gone. Do you have old disks, computers, or files you want to see again? We can help you get there.
You send us your disks, and we send you converted results you can read. It's as simple as that. We have decades of experience working with computer storage. We can help you with yours.
Copyright © 2019 RetroFloppy. Powered by WordPress. Theme: Esteem by ThemeGrill.


ARDMORE, PA (TheSpread) – The second day of the U.S. Open is complete and Phil Mickelson has put himself in good position to win.
According to oddsmakers from Bovada.lv, Mickelson is now the favorite to win this tournament, as he has 5/1 odds to win. Other short odds to win are Luke Donald (6/1) Tiger Woods (6/1) and Justin Rose (7/1).
Most, but not all, have completed their second round, including Mickelson. Lefty shot a 2-over 72 on Friday, which actually kept him in good position. He is now 1-under for the tournament and tied with Billy Horschel for the lead heading into the third round.
Donald was the sole leader at one point during Friday, but he ended up posting a 72 of his own for the second round, which leaves him at even par for the tournament and in a tie for third with four others.
Woods posted an even-par 70 on Friday, as he grinded through his second round and continued to battle an elbow injury that he incurred on Thursday. Woods is 3 over for the tournament and in a tie for 17th.
Rose is one of the five golfers sitting at even par for the tournament. He posted a 1-under 69 on Friday.
The 2013 U.S. Open continues on Saturday, June 15 and is scheduled to conclude on Sunday, June 16 from Merion Golf Club in Ardmore, Pennsylvania. For a complete look at the odds to win the 2013 U.S. Open, see below.


Are you a customer? Offer Aleksandra work on your next project. A freelancer? Register your profile and start earning right now.
Curious, open-minded and motivated internet marketer. I've built my skills and knowledge through various professional experiences. My everyday goal is to put all my professionalism into my client's projects, to make them grow and go a step further.
I believe the message has to create the design and that a good project is a mix of good research and a lot of work.
I'm always looking for new projects and challenges.


A great way to add style to your office, this rustic wood pencil cup features a gleaming piece of Natural carved arrowhead agate. This Color Natural can range from Gray to Cream and anything in between. If you are looking for a specific color... Please just email us and ask. We love custom orders. Perfect for giving your decor a rustic cool look.
In response to differences in temperature and pressure, magma is expelled from the Earth crust where it cools and becomes the beautiful stone known as Agate. They are most commonly found in places such as the United States, India, Morocco, Brazil and Africa and are found in a variety of colors. Considered a stone of stability, harmonizing physical, emotional and psychological balance.Please note: Due to the use of natural materials, each piece is unique and may vary from image shown.


text:
package com.lab.servlet.user;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.lab.po.UserInfo;
import com.lab.service.UserService;
import com.lab.service.impl.UserServiceImpl;

public class UserUpdateServlet extends HttpServlet {

	/**
	 *
	 */
	private static final long serialVersionUID = 1L;
	private UserService userService = new UserServiceImpl();

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		this.doPost(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		int userID = new Integer(URLDecoder.decode(req.getParameter("userId"), "utf-8").trim());
		UserInfo userInfo = userService.getByID(userID);
		boolean isVaild = false;
		if (userInfo != null && req.getParameter("newPwd") != null && !req.getParameter("newPwd").trim().isEmpty()) {
			userInfo.setUserPwd(URLDecoder.decode(req.getParameter("newPwd"), "utf-8"));
			if (userService.update(userInfo)) {
				isVaild = true;
			}
		}

		resp.setCharacterEncoding("utf-8");
		PrintWriter out = resp.getWriter();
		if (isVaild) {
			out.print("{\"isUpdate\":\"" + "true" + "\"}");
		}else {
			out.print("{\"isUpdate\":\"" + "false" + "\"}");
		}
		out.flush();
		out.close();
	}
}

redpajama_set_name: RedPajamaGithub


Assists lenders who offer government-guaranteed lending in assessing the size, viability and legitimacy of business lending applicants.
Provides On-Site Verification of applicant's physical location and business operation.
Satisfies the site visit requirement of SBA as part of Its 7(a) lending program.
Substantiates representations made on SBA lending application.
The SBA guarantees business loans to businesses based on specific aspects of the business and its principals. Some of the key factors of eligibility are based on what the business does to receive its income, the character of its ownership and where the business operates.
and a national network of well-trained, vetted professional inspectors. Metro Inspections will assign an inspector to visit the business location and verify the applicant's operations, locations and type of business conducted. While there are only a few items the SBA requires verification of, this is a unique opportunity to use the visit as an underwriting tool to verify any other factors the lender deems relevant. Metro Inspections will then analyze, scrutinize, and compile the results in order to submit them to the Provider through our state of-the-art Inspection Management System. The SBA lender is then able to assess the findings as they make final determination on the approval for business lending.


Although the different organs of the digestive tract are specialized for digesting different types of food, the basic chemical process of digestion is the same for fats, proteins, and carbohydrates. In every case, this process requires enzymes. Enzymes are catalysts, substances that speed the rate of chemical reactions, but are not themselves changed or used up in the reaction. All enzymes are proteins, and they are highly specific in their actions. In digestion, an enzyme acts only in a certain type of reaction involving a certain type of nutrient molecule. For example, the carbohydrate-digesting enzyme amylase only splits starch into the disaccharide (double sugar) maltose. Another enzyme is required to split maltose into two molecules of the monosaccharide (simple sugar) glucose. Other enzymes split fats into their building blocks, glycerol and fatty acids, and still others split proteins into smaller units called peptides and into their building blocks, amino acids.
Because water is added to nutrient molecules as they are split by enzymes, the process of digestion is referred to chemically as hydrolysis, which means "splitting by means of water." About 7 liters of water are secreted into the digestive tract each day, in addition to the nearly 2 liters taken in with food and drink.
You can now understand why so large an amount of water is needed. Water not only is used to produce digestive juices and to dilute food so that it can move more easily through the digestive tract, but also is used in the chemical process of digestion itself.
Figure 15-4 The digestive system.
Let us see what happens to a mass of food from the time it is taken into the mouth to the moment that it is ready to be absorbed. In the mouth, the food is chewed and mixed with saliva, softening it so that it can be swallowed easily. Salivary amylase initiates the process of digestion by changing some of the starches into sugar.
Digestion in the Stomach When the food reaches the stomach, it is acted on by gastric juice, with its hydrochloric acid (HCl) and enzymes. The hydrochloric acid has the important function of breaking down proteins and preparing them for digestion. In addition, HCl activates the enzyme pepsin, which is secreted by gastric cells in an inactive form. Once activated by hydrochloric acid, pepsin works to digest protein; this enzyme is the first to digest nearly every type of protein in the diet. The stomach also secretes a fat-digesting enzyme (lipase), but it is of little importance in adults. The food, gastric juice, and mucus (which is also secreted by cells of the gastric lining) are mixed to form chyme. This semiliquid substance is moved from the stomach to the small intestine for further digestion.
* Lipase. After bile divides fats into tiny particles, the highly active pancreatic enzyme lipase digests almost all of them. In this process, fats are usually broken down into two simpler compounds, glycerol (glycerin) and fatty acids, which are more readily absorbable. If pancreatic lipase is absent, fats are expelled with the feces in undigested form.
* Amylase. This enzyme changes starch to sugar.
* Trypsin. This enzyme splits proteins into amino acids, which are small enough to be absorbed through the intestine.
* Nucleases. These enzymes digest the nucleic acids DNA and RNA.
It is important to note that most digestion occurs in the small intestine under the action of pancreatic juice, which has the ability to break down all types of foods. When pancreatic juice is absent, serious digestive disturbances always occur. The small intestine also produces a number of enzymes, including three that act on complex sugars to transform them into simpler, absorbable forms. These enzymes are maltase, sucrase, and lactase, which act on the disaccharides maltose, sucrose, and lactose, respectively.


text:
Molybdenite Minerals
87 entries of Molybdenite Mineral Gallery
Andradite Garnet with Molybdenite from M.G.L. Tungsten Mine, Nightingale District, Pershing County, Nevada
Bismuth with Molybdenite from Wolfram Camp, Mareeba Shire, Queensland, Australia
Ferrimolybdite and Molybdenite from Smithfield Township, Ontario, Canada
Molybdenite from McCarthy, Alaska
Molybdenite from Quebec, Canada
Molybdenite from Ossipee Gulch (Raccoon Gulch), Folsom Brook, Center Ossipee, Carroll County, New Hampshire
Molybdenite from Crown Point Mine, Chelan County, Washington
Molybdenite from Shirakawa Mine, Honshu, Japan
Molybdenite from Crown Point Mine, Holden, Chelan County, Washington
Molybdenite from La Motte Township, Quebec, Canada
Molybdenite from Renfrew, Ontario, Canada
Molybdenite from Campo, San Diego County, California
Molybdenite from Oxford Quarry, Warren County, New Jersey
Molybdenite from Moly Hill Mine, La Motte Township, Quebec, Canada
Molybdenite from Niederpobel Tin Mine, Erzgebirge, Saxony, Germany
Molybdenite from Wolfram Camp, Mareeba Shire, Queensland, Australia
Molybdenite from Strawberry Tungsten Mine, Madera County, California
Molybdenite from Kingsgate, New South Wales, Australia
Molybdenite from Goodall Quarry, Sanford, York County, Maine
Molybdenite from Riviere Heva, Quebec, Canada
Molybdenite from Renfrew County, Ontario, Canada
Molybdenite from Bear Mountain State Park, Orange County, New York
Molybdenite from Franklin, Sussex County, New Jersey
Molybdenite from Cadillac Moly Mine, Preissac, Abitibi-Temiscamingue, Québec, Canada
Molybdenite from Sachs Mine, New South Wales, Australia
Molybdenite from Holt's Ledge, Lyme, Grafton County, New Hampshire
Molybdenite from North Moat Mountain, Bartlett, Carroll County, New Hampshire
Molybdenite from near the California Mine, Mount Antero, Chaffee County, Colorado
Molybdenite from Amax Mine, Climax, Fremont Pass, Lake County, Colorado
Molybdenite (spiral-growth) from Moly Hill Mine, La Motte Township, Quebec, Canada
Molybdenite and Chalcopyrite from West Cumberland Iron Mining District, Cumbria, England
Molybdenite and Molybdite from Climax Mine, Lake County, Colorado
Molybdenite and Powellite from Stony Creek Mills, Berks County, Pennsylvania
Molybdenite in Quartz from Schlaggenwald, Horni Slavkov, Bohemia, Czech Republic
Molybdenite in Quartz from Moly Hill Mine, La Motte Township, Quebec, Canada
Molybdenite in Quartz from Wolfram Camp, Mareeba Shire, Queensland, Australia
Molybdenite in Quartz from Moly Hill Mine, La Motte Township, Québec, Canada
Molybdenite in Quartz from Climax Mine, Fremont Pass, Leadville District, Lake County, Colorado
Molybdenite in Serpentine from Royal Green Quarry, near Phillipsburg, Warren County, New Jersey
Molybdenite on Quartz from Kingsgate Mines, Glen Innes, New South Wales, Australia
Molybdenite on Quartz from Moly Hill Mine, La Motte Township, Quebec, Canada
Molybdenite on Quartz from King's Gate, New South Wales, Australia
Molybdenite on Vesuvianite from Goodall Farm Quarry, Sanford, York County, Maine
Molybdenite with minor Molybdite from Phillipsburg, Warren County, New Jersey
Molybdenite with Pyrite from Squaw Peak, south of Camp Verde, Yavapai County, Arizona
Molybdenite with Pyrrhotite from Chungju, Chungcheongbukdo, South Korea
Molybdenite, Actinolite, Powellite from Gold Hill Mine, Tooele County, Utah
Molybdenite, Fluorite, Quartz, Muscovite from (Ganzhou), (Jiangxi Province), China
Powellite pseudomorphs after Molybdenite with Molybdenite on Vesuvianite from Goodall Farm Quarry, Sanford, York County, Maine
Scheelite with Molybdenite from Tae Wha Mine, Chungju, Chungchongpukdo, South Korea
Szenicsite, Powellite and Powellite pseudomorphs after Molybdenite from Jardinera #1 Mine, Tierra Amarilla, Inca de Oro, Chile (Type Locality for Szenicsite)


text:
How Literary Realism Impacted American Literature
By Nicole H.
American literary realism defined writing from the late 1800s to the early 1900s, and it remains a theme of literary criticism today.
In the 18th century, literature tended to be highly romantic in nature. Literary realism hit the scene late in the 19th century, and there was a dramatic shift in style.
Instead of romanticized stories and scenes, literary realism was a literary movement that portrayed everyday life and experiences as they happened, with minimal symbolism but instead a focus on truthful storytelling.
Though it was popular in the 19th century, literary realism remains a common type of writing in modern literature. If you are considering a career or hobby in fiction writing, learning how to embrace this style is helpful.
A History of Literary Realism
History of American Literary Realism
Characteristics Of Realist Writers And Realist Novels
Types of Literary Realism
A Final Word About Literary Realism
FAQs About Literary Realism
In 18th century writing and art, Romanticism reigned. Exotic and dramatic writing was commonplace. In the 19th century France, this started to change.
In France, writers started to publish works that made stories out of everyday experiences in serial form through newspapers. Honore de Balzac was one of the first of these writers. He wrote stories with complicated characters that had detailed observations about the world around him.
Gustave Flaubert followed close behind. He defined the realist narration form that is still showing up in literature today. Soon the writing style jumped across the ocean and began to impact writers in America.
By Jean Alfred Gérard-Séguin – Own work, Public Domain, https://commons.wikimedia.org/w/index.php?curid=25240843
Realism soon took up root in American literary history, creating some of the most-studied American works. William Dean Howells took up the mantel of realism in America and became the first American realist author. His novels explored middle-class life in the late 1800s in America.
Samuel Clemens, better known as Mark Twain, followed not long after. His book The Adventures of Huckleberry Finn, which hit the shelves in 1884, was the first novel that captured the distinct voice and culture of the American South.
Other Examples of American Literary Realism
When the works of Howells and Twain started to gain popularity, the literary style took root. Other popular authors and works include:
Stephen Crane: The Red Badge of Courage explores life on the battlefield during the Civil War.
John Steinbeck: This Nobel Prize-winning author wrote Grapes of Wrath, a novel that showed the truly horrifying nature of the Great Depression.
Upton Sinclair: Sinclair used his writing to call out the improper political and business practices of the meat-packing industry in his novel The Jungle.
Edith Wharton: This American novel and short-story writer explored the upper-class lifestyle of the early 1900s.
Henry James: James wrote a number of famous American works, including The Turn of the Screw and The Portrait of a Lady.
Other Examples of Literary Realism in Literature
Other European authors who wrote about real-life include:
George Eliot: This English novelist was actually the pen name for Mary Ann Evans, and she wrote seven novels about Victorian Europe, including Silas Marner and Middlemarch.
Charles Dickens: Social critic and English literature contributor, Dickens explored the plight of the poor and working-class people in books like Oliver Twist and A Tale of Two Cities.
Emile Zola: This French novelist and playwright wrote Les Rougon-Macquart, which explored life in mid-1800s France.
Jane Austen: Jane Austen used her books to explore and critique the landed gentry of Britain in the late nineteenth century.
Realist novels take place in the mid-1800s, just after the American Civil War, and into the early twentieth century. most novels follow the middle and lower classes, but some will explore upper-class themes.
The main characteristic of these novels is the exploration of real life. They often critique social injustice or explore the culture of a particular area of the country. Realist authors explore everyday experiences, even those considered mundane, in an effort to explore what society is like at the time and do so as truthfully as possible.
Literary realism can include several subtypes of literature, including:
Social realism: Socialist realism focuses on the poor or working class, often making a social or political statement. These authors often hoped to create social change through their writing.
Magical realism: This form of literary realism adds magical elements to an otherwise normal world, in a way combining literary realism with fantasy writing.
Naturalism: Naturalistic realism is a form of realism influenced by Darwin's theory of evolution. This form of realism, common in Emile Zola's writing, focuses on the belief that the scientific method can explain events in society and the environment.
Psychological realism: This form of writing is driven by the characters of the story and their psychological motivations.
Not all stories have to be fanciful, exotic experiences. Sometimes, real life is just as interesting as imaginative prose. In American fiction writing, realism is a popular literary style.
Literary realism often explores social problems through fiction writing. Many writers created change through their writing as they exposed the problems of modern society, especially those facing middle and lower classes of society.
These novels remain popular today because of the way they capture everyday life and make it beautiful.
Who Are The Three Leading Figures Of American Literary Realism?
According to Washington State University, the top examples of literary realism in American literature were Mark Twain, William Dean Howells, and Henry James. Each of these authors wrote stories with minimal symbolism but that accurately portrayed the reality of the time frame they were writing about.
Who started realism in literature?
Though there are many American authors who wrote with realism, the movement started with a French writer, Honore de Balzac.
This French novelist wrote with an unfiltered view of society and its ills. His writing set the foundation for the realism movement in literature, which eventually filtered into American novelists.
Other sources attribute the rise of realism to Norwegian playwright Henrik Johan Ibsen. Ibsen wrote A Doll's House, which has become one of the most performed plays across the globe.
Nicole H.
Nicole Harms has been writing professionally since 2006. She specializes in education content and real estate writing but enjoys a wide gamut of topics. Her goal is to connect with the reader in an engaging, but informative way. Her work has been featured on USA Today, and she ghostwrites for many high-profile companies. As a former teacher, she is passionate about both research and grammar, giving her clients the quality they demand in today's online marketing world.


To promote awareness of the O2 Gurus and O2's Christmas trading campaign customers were asked to share their Christmas gifting dilemmas and in response were given a bespoke gifting recommendations. These were delivered via either bespoke Vines, gift tag images or tweets. Some customers were also selected at random to win prizes made up of O2's products.


The Dangerous For Environment TIE027P sign will alert people to the fact that they will need to be especially cautious with a substance as there is the possibility of damage to the environment. The sign uses the symbols of trees and fish having been killed, through this associated pollution.
You may have a duty to protect your local environment, especially if you are using such pollutants, ensure that everyone is as cautious and helps to keep you on the right side of the law.


Haryana SSC Gram Sachiv Patwari Online Form 2019 : Haryana Staff Selection Commission HSSC and Haryana Police Department are Invited to Online Application Form For The Gram Sachiv and Canal Patwari post Recruitment 2019.Those candidates are Interested for these Post They Should Apply Online Before Read full Notification.
Canal Patwari :- Class 10th (High School) Exam Passed From Any Recognized Board in India.
Gram Sachiv :- Class 12th (Intermediate) exam Passed From Any Recognized Board in India.
Selection on the Basis of Exam and Merit List.


For more than 50 years, Christer R. Christensson has been collecting motorcycles, resulting in a world-renowned collection that is both extensive and representative of the very best of the best when it comes to motorcycle design and technology. Working alongside his colleague, Ove Johansson, and his highly skilled team of restorers, Christensson has built the MC Collection of Stockholm into a more than 400-motorcycle presentation that establishes the motorcycle not merely as a machine, but as a contemporary work of art and mechanical sculpture.
A truly international affair hosting motorcycles from marques around the world, the collection pays homage to the design engineers and motorcycles that have shaped the industry for more than 100 years, starting with the very first motorcycle produced, the Hildebrand & Wolfmüller of 1894. The MC Collection of Stockholm is a trip through time and space, showcasing motorcycles from pinnacle times in motorcycle history, such as early 20th-century board-track racing in America and the collapse of the English motorcycle industry in the '60s, when Japanese marques took hold of the motorcycle industry worldwide.
Christensson re-housed his unique personal collection in 1999 in a showroom near Stockholm built to both serve his collection's needs and to share a selection of about 140 of his motorcycles with the general public, providing an opportunity for enthusiasts to closely study the motorcycles and how they have evolved since 1894. Most recently, an opportunity arose for Christensson and Johansson that was just too good to pass on: residence at the Tidö Castle, one of Sweden's best-preserved Baroque palaces in Dutch Renaissance style. While something to celebrate, spatial constraints at the castle also mean the pair have to part with a large portion of their meticulously maintained motorcycle collection, and as such, will now be offering 235 fine examples at Mecum's 28th Annual Las Vegas Vintage and Antique Motorcycle Auction this January.
An undeniably impressive slice of the Swedish collection, those on offer range from the aforementioned 1894 Hildebrand & Wolfmüller Replica and early American classics like a 1905 Indian Camelback, a 1914 Flying Merkel V-Twin and a 1917 Pope Model T-17, to a 1978 Ducati NCR Racer, a 1968 Munch 4TT Mammoth and more. Highlights abound throughout the collection and represent marques worldwide, including a 1924 NUT Twin, a rarely seen 1929 Opel Neander, a 1927 Husqvarna 180 and even the elusive 1939 Crocker Big Tank, the venerable release from the short-lived Crocker Motorcycle Company. When the Las Vegas auction rolls around this January, one thing's for certain: motorcycle enthusiasts will have a rare opportunity to take home a piece of this unique and renowned collection with 235 motorcycles from the MC Collection of Stockholm set to be offered on Friday, January 25.


text:
RAA Travel / Discover Spain and Portugal
Discover Spain and Portugal
14 days and 13 nights Trafalgar guided tour
19 meals, taste Port in Porto, 16th century convent stay Included
20 Dec 2021 - 22 Oct 2023 Selected departures
Starts Madrid/ends Barcelona
Book by 28 October 2023
Brimming with cultural, historical, and artistic delights, embark upon a classic exploration of the Iberian Peninsula. This journey boasts a roll call of classic Spanish cities: Madrid, Toledo, orange-scented Seville (and resting place of Christopher Columbus), Granada, Valencia, and incredibly cultural Barcelona. With a local specialist guide, learn more about the 'Way of Saint James' – a life-changing pilgrimage, in Santiago de Compostela.
In Portugal, discover a breathtaking line-up of places to see, and things to eat and drink. Visit the port wine capital of the planet — Porto, Portuguese capital Lisbon — the city built on seven hills and the miraculous Shrine of Fatima.
Stay at an atmospheric hotel in Porto, built from the ruins of a 16th-century convent, and sample the famous tipple at a Port cellar. Follow the road to the Shrine of Fatima, the site of a celebrated religious miracle. In Lisbon, visit the UNESCO-listed Hieronymite Monastery. No visit is complete without trying perhaps Portugal's most famous sweet export – the pasteis de nata – an egg custard tart pastry dusted with cinnamon. The best place to buy these blissful little tarts is in Lisbon at Pastéis de Belém. Here, more than 20,000 tarts are made daily.
In Seville, visit the largest Gothic Cathedral in the world, explore the fine art of olive oil production and enjoy a memorable dinner at an olive oil estate. All signs point to the Alhambra in Grenada. Built towards the end of Islamic rule in Spain, the Alhambra, a palace and fortress complex is one of Spain's jewels and a place you'll admire the intricate design and detail at every turn.
In Valencia, sample the local horchata drink and delve into the city's 2000-year-old history, before arriving at Barcelona. See Antonio Gaudi's unfinished masterpiece – La Sagrada Familia, a cathedral of epic design. Pay tribute to Christopher Columbus at the monument that bears his name and enjoy time to see this exciting city at your own pace. Barcelona is an incredibly exciting city with lots to see and do, so do consider extending your stay here.
Gourmet food and drinks
13 nights accommodation
19 meals
Explore Toledo, Madrid, Santiago de Compostela, Porto, Lisbon, Seville and Barcelona with a Local Specialist
Discover Segovia, Zamora and Valencia
Visit Santo Tomé and the synagogue in Toledo, the cathedral and Praza do Obradoiro in Santiago de Compostela, the Stock Exchange Palace and a local port wine cellar in Porto, the Shrine at Fátima, the Hieronymite Monastery in Lisbon, Seville Cathedral, the Alhambra Palace in Granada and Montjuïc Hill in Barcelona
View the Roman Aqueduct and Alcazar in Segovia, the cathedral in Zamora, the Belém Tower in Lisbon, the Giralda Bell Tower in Seville, the cave homes of Guadix, the Serrano and Quart Towers and the city of Arts and Sciences complex in Valencia and La Sagrada Família and Plaça de Catalunya in Barcelona
See the Monument to the Discoveries in Lisbon
Luxury air-conditioned coach with Wi-Fi in most countries or alternative transportation (such as rail journeys)Expert travel director
All hotel tips, charges and local taxes
All porterage and restaurant gratuities
Audio headsets for flexible sightseeing
Madrid - Toledo - Segovia - Zamora - Santiago de Compostela
Hola Madrid
Kick-start your epic encounter with Spain and Portugal in Europe's highest capital city, Madrid. Spend your day rambling along tree-lined boulevards and people-watching in the city's lively squares before joining your fellow travellers and Travel Director for a Welcome Reception and orientation drive past some of Madrid's most iconic sites.
Hotel - Barceló Imagine
Welcome Reception
Admire the Sights of Toledo and Madrid
We journey south for an excursion to the hilltop city of Toledo, where we'll join our Local Specialist for a walking tour. Visit the Church of Santo Tomé, home to El Greco's most famous painting, 'The Burial of the Count of Orgaz', and visit the former synagogue of Santa Maria la Blanca. This afternoon, join a Local Specialist for a sightseeing tour of the Spanish capital, which includes views of the Royal Palace, the former residence of the Spanish royal family and the Cibeles Fountain.
OPTIONAL EXPERIENCE
Dinner and Discovery in Downtown Madrid
Join us this evening as we scratch beneath the surface of some lesser-known aspects of Madrid's city centre. Then, we'll settle in for dinner, along with musical entertainment and finish up with a spin around some of the wonderful squares and fountains of magical Madrid.
Adult Price: €61.00*
* The Optionals and pricing listed here are a guideline only and subject to change.
Journey to Segovia and Zamora
Venture to Segovia and see the Roman Aqueduct, by far the most impressive Roman structure in Spain - delivering drinking water across its impressive 160 arches to the people of Segovia in ancient times. View the Alcázar of Segovia and the city's medieval and Moorish architecture. Travel to the city of Zamora in the Castilla y León region. Your orientation tour includes views of the cathedral and the Church of Mary Magdalene. Later this evening, why not follow your nose to a cosy local spot and relax with tapas and some refreshingly fruity sangria to toast the day.
Hotel - NH Palacio del Duero
Breakfast, Dinner
A Pilgrimage to Santiago de Compostela
Travel to Santiago de Compostela, where you'll join a Local Specialist, who will share insights into the 'Way of Saint James' and explain why thousands of people attempt the life-changing pilgrimage annually. Visit the vast Cathedral, reputed to be the final resting place of Saint James the Great, and the Praza do Obradoiro, a square dominated by four architectural styles.
Hotel - Eurostars Gran
Porto - Fatima - Lisbon - Seville
Journey to Scenic Porto
Embark on a sightseeing tour with a Local Specialist today in Porto. Wander past Baroque churches and along the winding lanes that tumble down towards the Douro. See the remarkable bridges that span the river, the medieval Ribeira Quarter and the city port. Visit the Stock Exchange Palace with its splendid Arabian Hall inspired by Granada's Alhambra, before you Dive Into Culture and the centuries-old tradition of local Port production at a tasting in a Port cellar. Spend the rest of the afternoon strolling through the historic centre of Porto. Check in to your impressive Stays With Stories hotel, the Neya Porto, built from the ruins of a convent founded in 1533. Discover the fascinating history of the Convento Madre Deus de Monchique turned hotel while admiring the magnificent Douro River views.
Hotel - Neya
Douro Cruise And Dinner
Enjoy a relaxing and leisurely cruise along the Douro River. You'll have a chance to see two medieval "world heritage" cities plus five impressive bridges, one of them the famous UNESCO-listed Eiffel bridge. Afterwards, savour a typical meal in the Medieval Ribeira Quarter
Onwards to Fátima and Lisbon
Follow the road taken by pilgrims over the last 100 years to the Shrine at Fátima, site of a celebrated religious miracle. We arrive in colourful Lisbon later – our home for the next two nights. This evening perhaps enjoy a traditional Portuguese dinner amidst the heart-wrenching, melancholic sounds of the fado.
Hotel - VIP Grand
Portuguese Fado Evening Of Music & Song With Dinner
Tonight enjoy a unique experience of traditional Lisbon nightlife. You'll savour a typical meal with local aperitifs and wines and hear beautiful, traditional Fado singing, an expressive musical art more than 200 years old. Cancellation within 24 hours will incur a 50% cancellation fee.
Discover Lisbon's Treasures
Delve into Lisbon's centuries-old seafaring heritage today, paying tribute to the brave men who set off from these shores to discover a new world. We'll see the shimmering white Monument to the Discoveries, the iconic suspension bridge spanning the River Tagus, and Belém Tower when we join a Local Specialist on a sightseeing tour of Lisbon. We'll Dive Into Culture at the UNESCO-listed Hieronymite Monastery, an exquisite testament to 16th-century Manueline architecture and art. Join an Optional Experience to the historic towns of Cascais and Sintra.
Gourmet Dinner, Parliament, Exclusive Estrela and Evening Orientation
Your opportunity to view the exclusive district of Estrela, its park, basilica and the Portuguese Parliament, on the way to a delicious gourmet dinner. You'll finish the evening with a drive along the banks of the mighty Tagus River.
Seafood Dinner By The Tagus River
Take a ferry across the mighty Tagus River and enjoy typical Portuguese seafood and fish specialities at a local restaurant. After dinner, we'll cross the impressive Suspension Bridge for a sweeping view over the Portuguese capital. On occasion the ferry may not be available and we will travel over the bridge both ways.
The Golden Triangle: Sintra, Cascais & The Estoril Coast
We'll venture outside Lisbon with our Local Specialist today. After passing through the fashionable resort of Estoril, we'll explore the picturesque fishing village of Cascais, with its beautiful array of mansions and exclusive residences. To complete the Golden Triangle, we'll visit one of the impressive Royal Palaces of Portugal.
On to Seville
We travel east through Portugal's picturesque rural landscapes of the Alentejo – the country's cork capital and cross into Spain, journeying through the province of Huelva, renowned for its Jabugo ham, before arriving in Seville. This evening, explore the fine art of olive oil production at a Be My Guest experience and Connect With Locals over a memorable dinner at an olive oil estate.
Hotel - Meliá Lebreros
Breakfast, Be My Guest dinner
Explore Spectacular Seville
The charisma of Seville is unmistakable. Join a Local Specialist for a walking tour through the city. View the symbolic Giralda Bell Tower, see the tiled fountains, pavilions and lush palms in the Maria Luisa Park and walk through the imposing Plaza de España. Later, we'll stroll through the historic Jewish Quarter before visiting the largest Gothic Cathedral in the world.
Discover The Origin Of "Tapas" & Evening In Old Seville
Join us for a dinner of mouth-watering tapas-style specialties. You'll get the chance to taste different flavours and wines and dine like a local in the charming old quarter of Seville.
Flamenco: Experience the Best Show in Town
Discover the passion, rhythm and magic of an Andalusian flamenco show with us this evening. We've organised tickets to the best show in town, where you'll experience 90 minutes of memorable entertainment with and included drink.
The Moorish Alcazar And Plaza América
Today, with our Local Specialist, we'll visit the elegant 14th-century Moorish Alcazar, set in its own beautiful gardens. The gardens were recently used as the setting for the Water Gardens of Dorne in the Game Of Thrones series. We'll also journey to the famous exhibition site of Plaza América - a must for any visitor to Seville. Cancellation within 24 hours will incur a 50% cancellation fee.
Flamenco, the best show in town with a three-course dinner
This evening you'll discover the magic, rhythm and passion of flamenco, while being served a three-course dinner of Andalusian specialties with drinks included. We've organised tickets to the best show in town. You won't soon forget this incredibly memorable ninety-minute experience.
Days 10 - 14
Granada - Valencia - Barcelona
Off to Granada
Multicultural Granada takes centre stage today as we visit the magnificent Alhambra in the company of a Local Specialist. A fine example of Moorish architecture, the Alhambra complex was built during the 14th century towards the end of Islamic rule in Spain. Wander through the exotic water gardens of the Generalife, the royal Summer Palace, once linked to the other palaces by a covered walkway across the ravine, and admire the intricate design and detail around every turn.
Hotel - Abades Nevada Palace
Albaicín And The Royal Chapel
With our Local Specialist, we'll enjoy a leisurely walking tour through the Albaicín UNESCO World Heritage Site – a maze of narrow streets and Moorish splendour. You'll get to explore the Catholic Monarchs' tombs and some of their treasures at the Royal Chapel, and wander through the picturesque Alcaicería quarter.
Onwards to Valencia
This morning, we travel via the Mora Pass to Guadix in the northern foothills of the Sierra Nevada mountains where you will see the whitewashed troglodyte dwellings lodged in the ochre-coloured cliffs of the surrounding area. We travel to Valencia, where we'll stay overnight to view the Bullring and admire the architecture of its medieval cathedral and the Serrano and Quart Towers. Embrace the city's spirit of innovation and stop to view the City of Arts and Sciences, a large-scale urban recreation centre for culture and science, designed by Santiago Calatrava. There's also time to Dive Into Culture and enjoy the local horchata drink, made from the little-known chufa, or tiger nut, which is only found in Valencia. You'll get to savour this refreshing sweet treat, a favourite with the locals, at a charming Valencia horchatería.
Hotel - Silken Puerta
Valencia Dinner and Discovery
We'll delve into the country's third-largest city to enjoy its Mediterranean verve. Vibrant and modern, Valencia still retains much of its past, going back to its Roman foundation 2,000 years ago. The iconic dish "Paella" originated here and tonight we'll learn about its traditions and enjoy this singular Spanish fare during a typical meal in one of the city's most popular restaurants.
See the Sights of Barcelona
Head north along the coast through the Levant region and stop at Peñíscola, the 'City in the Sea', to view the ancient castle of the 'Spanish Pope', built by the Knights Templar and used in the film, 'El Cid'. We continue along the Costa Dorada to Barcelona with its whimsical Gaudí architecture. Join a Local Specialist and see the unfinished La Sagrada Família then explore the Plaça de Catalunya and pay tribute to Christopher Columbus at the monument that bears his name.
Hotel - Tryp Apolo
Gothic Quarter and Dinner
Work up an appetite with a walking tour of the old Gothic Quarter, where Barcelona was born. Meander through the beautiful medieval streets and century-old architecture with your Local Specialist. Then we'll take you to the marina of Port Olympic, where you'll enjoy Mediterranean food in one of our favourite local eateries.
Barcelona Your Way
Embrace the charm of Barcelona, ramble through El Born for delicious tapas or consider joining an Optional Experience to the mountaintop monastery of Montserrat to see the shrine of the Black Madonna - affectionately known in Catalonia as La Moreneta - or spend the rest of the day exploring the city's enchanting barrios. This evening, we join our fellow travellers and Travel Director for a Farewell Dinner.
Breakfast, Farewell Dinner
Mystical Montserrat
Today, with our Local Specialist, we'll take a drive to the enchanting and mystical mountain of Montserrat, with its breathtaking views and spectacular scenery. While there, we'll visit the Benedictine monastery to view the famed Black Madonna.
Journey home
For now it's adios to Spain at the end of a memorable holiday.
All optional experiences for this trip
Book with your travel director when you travel
Where you'll be
Discover Spain and Portugal - tour map
From $5,050 per adult twin share
Solo traveller pricing - on application. Please ask your RAA Travel sales consultant for details.
20 December 2021 - 22 October 2023
A first non-refundable deposit of $200 per adult is due within 7 days of booking.
Gold Seal protection
Available for $99 per person. For more information on Trafalgar's Gold Seal protection, click here.
Pre/post tour accommodation
Extend your stay in Madrid before the tour, and/or Barcelona after the tour. Ask for details.
Price advertised is per person adult twin share in AUD. Subject to availability. A non refundable deposit is required at time of booking. Cancellation fees may apply. Please speak to your RAA travel advisor for more details. Trafalgar - Treasures of Spain and Portugal end Barcelona - Tour code - STSP
This trip is: Active
Lively pace. Lots of walking on uneven ground, cobblestone surfaces, through soft sand and up and down stairs or slopes. You must be able to tolerate local conditions such as humidity, heat, and high altitude. You must have a satisfactory level of physical and respiratory fitness. You must be able to get on/off transportation multiple times unassisted, manage distances at airports and railway stations without assistance, and handle your own luggage as required.
Trip code: TRAF174
Enquire about Discover Spain and Portugal