text:
// Copyright (c) 2009 - Mozy, Inc.

#include "mordor/streams/memory.h"
#include "mordor/streams/buffered.h"
#include "mordor/streams/null.h"
#include "mordor/streams/pipe.h"
#include "mordor/streams/singleplex.h"
#include "mordor/streams/test.h"
#include "mordor/test/test.h"
#include "mordor/thread.h"
#include "mordor/workerpool.h"
#include "mordor/streams/singleplex.h"
#include "mordor/streams/test.h"
#include "mordor/test/test.h"

using namespace Mordor;
using namespace Mordor::Test;

MORDOR_UNITTEST(BufferedStream, read)
{
    MemoryStream::ptr baseStream(new MemoryStream(Buffer("01234567890123456789")));
    BufferedStream::ptr bufferedStream(new BufferedStream(baseStream));
    bufferedStream->bufferSize(5);

    MORDOR_TEST_ASSERT_EQUAL(baseStream->size(), 20);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->size(), 20);

    Buffer output;

    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->read(output, 0), 0u);
    // Nothing has been read yet
    MORDOR_TEST_ASSERT_EQUAL(output.readAvailable(), 0u);
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 0);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 0);

    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->read(output, 2), 2u);
    MORDOR_TEST_ASSERT(output == "01");
    // baseStream should have had a full buffer read from it
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 5);
    // But the bufferedStream is hiding it
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 2);

    output.clear();
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->read(output, 2), 2u);
    MORDOR_TEST_ASSERT(output == "23");
    // baseStream stays at the same position, because the read should have been
    // satisfied by the buffer
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 5);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 4);

    output.clear();
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->read(output, 7), 7u);
    MORDOR_TEST_ASSERT(output == "4567890");
    // baseStream should have had two buffer-fuls read
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 15);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 11);

    output.clear();
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->read(output, 2), 2u);
    MORDOR_TEST_ASSERT(output == "12");
    // baseStream stays at the same position, because the read should have been
    // satisfied by the buffer
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 15);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 13);

    output.clear();
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->read(output, 10), 7u);
    MORDOR_TEST_ASSERT(output == "3456789");
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 20);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 20);

    // Make sure the buffered stream gives us EOF properly
    output.clear();
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->read(output, 10), 0u);
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 20);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 20);
}

MORDOR_UNITTEST(BufferedStream, partialReadGuarantee)
{
    MemoryStream::ptr baseStream(new MemoryStream(Buffer("01234567890123456789")));
    TestStream::ptr testStream(new TestStream(baseStream));
    BufferedStream::ptr bufferedStream(new BufferedStream(testStream));
    testStream->maxReadSize(2);

    Buffer output;

    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->read(output, 5), 5u);
    MORDOR_TEST_ASSERT(output == "01234");
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 6);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 5);

    bufferedStream->allowPartialReads(true);
    output.clear();
    // Use up the rest of what's buffered
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->read(output, 5), 1u);
    MORDOR_TEST_ASSERT(output == "5");
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 6);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 6);

    output.clear();
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->read(output, 5), 2u);
    MORDOR_TEST_ASSERT(output == "67");
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 8);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 8);
}

MORDOR_UNITTEST(BufferedStream, partialReadRawPointer)
{
    MemoryStream::ptr baseStream(new MemoryStream(Buffer("0123456789")));
    TestStream::ptr testStream(new TestStream(baseStream));
    BufferedStream::ptr bufferedStream(new BufferedStream(testStream));
    testStream->maxReadSize(2);

    char output[6];
    memset(output, 0, 6);

    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->read(output, 5), 5u);
    MORDOR_TEST_ASSERT_EQUAL((const char *)output, "01234");
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 6);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 5);
}

MORDOR_UNITTEST(BufferedStream, write)
{
    MemoryStream::ptr baseStream(new MemoryStream());
    BufferedStream::ptr bufferedStream(new BufferedStream(baseStream));
    bufferedStream->bufferSize(5);

    MORDOR_TEST_ASSERT_EQUAL(baseStream->size(), 0);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->size(), 0);

    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->write("abc", 3), 3u);
    MORDOR_TEST_ASSERT_EQUAL(baseStream->size(), 0);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->size(), 3);

    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->write("de", 2), 2u);
    MORDOR_TEST_ASSERT_EQUAL(baseStream->size(), 5);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->size(), 5);

    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->write("fgh", 3), 3u);
    MORDOR_TEST_ASSERT_EQUAL(baseStream->size(), 5);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->size(), 8);

    bufferedStream->flush();
    MORDOR_TEST_ASSERT_EQUAL(baseStream->size(), 8);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->size(), 8);
    MORDOR_TEST_ASSERT(baseStream->buffer() == "abcdefgh");
}

MORDOR_UNITTEST(BufferedStream, partialWriteGuarantee)
{
    MemoryStream::ptr baseStream(new MemoryStream());
    TestStream::ptr testStream(new TestStream(baseStream));
    BufferedStream::ptr bufferedStream(new BufferedStream(testStream));
    bufferedStream->bufferSize(5);
    testStream->maxWriteSize(2);

    MORDOR_TEST_ASSERT_EQUAL(baseStream->size(), 0);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->size(), 0);

    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->write("hello", 5), 5u);
    MORDOR_TEST_ASSERT_EQUAL(baseStream->size(), 2);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->size(), 5);

    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->write("abcdefghijklmnopqrstuvwxyz", 26), 26u);
    MORDOR_TEST_ASSERT_EQUAL(baseStream->size(), 28);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->size(), 31);

    bufferedStream->bufferSize(20);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->write("abcdefghijklmnopqrstuvwxyz", 26), 26u);
    MORDOR_TEST_ASSERT_EQUAL(baseStream->size(), 38);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->size(), 57);

    bufferedStream->flush();
    MORDOR_TEST_ASSERT_EQUAL(baseStream->size(), 57);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->size(), 57);
    MORDOR_TEST_ASSERT(baseStream->buffer() == "helloabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz");
}

MORDOR_UNITTEST(BufferedStream, unread)
{
    Stream::ptr baseStream(new MemoryStream(Buffer("01234567890123456789")));
    baseStream.reset(new SingleplexStream(baseStream, SingleplexStream::READ));
    BufferedStream::ptr bufferedStream(new BufferedStream(baseStream));
    bufferedStream->bufferSize(5);

    MORDOR_TEST_ASSERT_EQUAL(baseStream->size(), 20);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->size(), 20);

    Buffer output;
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->read(output, 6), 6u);
    MORDOR_TEST_ASSERT(output == "012345");
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 10);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 6);

    output.consume(3);
    bufferedStream->unread(output);
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 10);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 3);

    output.clear();
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->read(output, 6), 6u);
    MORDOR_TEST_ASSERT(output == "345678");
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 10);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 9);

    output.clear();
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->read(output, 6), 6u);
    MORDOR_TEST_ASSERT(output == "901234");
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 15);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 15);
}

MORDOR_UNITTEST(BufferedStream, find)
{
    MemoryStream::ptr baseStream(new MemoryStream(Buffer("01234567890123456789")));
    BufferedStream::ptr bufferedStream(new BufferedStream(baseStream));
    bufferedStream->bufferSize(5);

    MORDOR_TEST_ASSERT(bufferedStream->supportsFind());
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 0);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 0);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->find('0'), 0);
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 5);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 0);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->find("01234"), 0);
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 5);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 0);
    Buffer output;
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->read(output, 1), 1u);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->find("0123"), 9);
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 15);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 1);
}

MORDOR_UNITTEST(BufferedStream, findSanityChecks)
{
    MemoryStream::ptr baseStream(new MemoryStream(Buffer("01234567890123456789")));
    BufferedStream::ptr bufferedStream(new BufferedStream(baseStream));
    bufferedStream->bufferSize(5);

    // Buffer size is 5, default sanity size is twice the buffer size
    MORDOR_TEST_ASSERT_EXCEPTION(bufferedStream->find('\n'), BufferOverflowException);
    MORDOR_TEST_ASSERT_EXCEPTION(bufferedStream->find("\r\n"), BufferOverflowException);
    MORDOR_TEST_ASSERT_EXCEPTION(bufferedStream->find('\n', 20), UnexpectedEofException);
    MORDOR_TEST_ASSERT_EXCEPTION(bufferedStream->find("\r\n", 20), UnexpectedEofException);

    MORDOR_TEST_ASSERT_LESS_THAN(bufferedStream->find('\n', ~0, false), 0);
    MORDOR_TEST_ASSERT_LESS_THAN(bufferedStream->find("\r\n", ~0, false), 0);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->find('\n', 20, false), -21);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->find("\r\n", 20, false), -21);
}

static void throwRuntimeError()
{
    throw std::runtime_error("");
}

MORDOR_UNITTEST(BufferedStream, errorOnRead)
{
    MemoryStream::ptr baseStream(new MemoryStream(Buffer("01234567890123456789")));
    TestStream::ptr testStream(new TestStream(baseStream));
    BufferedStream::ptr bufferedStream(new BufferedStream(testStream));
    testStream->onRead(&throwRuntimeError);

    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 0);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 0);

    Buffer output;
    MORDOR_TEST_ASSERT_EXCEPTION(bufferedStream->read(output, 5), std::runtime_error);
    MORDOR_TEST_ASSERT_EQUAL(output.readAvailable(), 0u);
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 0);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 0);

    testStream->onRead(&throwRuntimeError, 2);
    // Partial read still allowed on exception (it's assumed the next read
    // will be either EOF or error)
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->read(output, 5), 2u);
    MORDOR_TEST_ASSERT(output == "01");
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 2);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 2);

    output.clear();
    // Make sure that's correct
    MORDOR_TEST_ASSERT_EXCEPTION(bufferedStream->read(output, 5), std::runtime_error);
    MORDOR_TEST_ASSERT_EQUAL(output.readAvailable(), 0u);
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 2);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 2);
}

MORDOR_UNITTEST(BufferedStream, errorOnWrite)
{
    MemoryStream::ptr baseStream(new MemoryStream());
    TestStream::ptr testStream(new TestStream(baseStream));
    BufferedStream::ptr bufferedStream(new BufferedStream(testStream));
    bufferedStream->bufferSize(5);

    MORDOR_TEST_ASSERT_EQUAL(baseStream->size(), 0);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->size(), 0);

    testStream->onWrite(&throwRuntimeError);
    MORDOR_TEST_ASSERT_EXCEPTION(bufferedStream->write("hello", 5), std::runtime_error);
    MORDOR_TEST_ASSERT_EQUAL(baseStream->size(), 0);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->size(), 0);

    testStream->onWrite(&throwRuntimeError, 3);
    // Exception swallowed; only 3 written to underlying stream (flush will
    // either clear buffer, or expose error); partial write guarantee still
    // enforced
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->write("helloworld", 10), 10u);
    MORDOR_TEST_ASSERT_EQUAL(baseStream->size(), 3);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->size(), 10);

    MORDOR_TEST_ASSERT_EXCEPTION(bufferedStream->flush(), std::runtime_error);
    MORDOR_TEST_ASSERT_EQUAL(baseStream->size(), 3);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->size(), 10);

    testStream->onWrite(NULL);
    bufferedStream->flush();
    MORDOR_TEST_ASSERT_EQUAL(baseStream->size(), 10);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->size(), 10);
}

MORDOR_UNITTEST(BufferedStream, seek)
{
    MemoryStream::ptr baseStream(new MemoryStream(Buffer("abcdefghijklmnopqrstuvwxyz0123456789")));
    BufferedStream::ptr bufferedStream(new BufferedStream(baseStream));
    bufferedStream->bufferSize(5);

    // We all start out at 0
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 0);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 0);

    // Seeking to current position doesn't do anything
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->seek(0), 0);
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 0);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 0);

    // Seeking with nothing in the buffer sets both streams to exactly
    // where we ask
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->seek(1), 1);
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 1);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 1);

    // Make sure the data corresponds to where we are
    Buffer buffer;
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->read(buffer, 2), 2u);
    MORDOR_TEST_ASSERT(buffer == "bc");
    // Buffered readahead of 5 + 1 (current pos)
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 6);
    // But we're really at 3
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 3);
    // Seeking to current position doesn't do anything
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->seek(3), 3);
    // Even to the underlying stream
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 6);
    buffer.clear();
    // Double-check the actual data again
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->read(buffer, 2), 2u);
    MORDOR_TEST_ASSERT(buffer == "de");
    // It should have been buffered and not touch the baseStream
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 6);
    // But did change our position
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 5);

    // Seeking outside of the buffer should clear it (and seek the baseStream)
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->seek(0), 0);
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 0);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 0);

    // Double-check actual data
    buffer.clear();
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->read(buffer, 2), 2u);
    MORDOR_TEST_ASSERT(buffer == "ab");
    // Buffered read-ahead
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 5);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 2);

    // Seek to the end of the buffer
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->seek(5), 5);
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 5);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 5);

    // Double-check actual data
    buffer.clear();
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->read(buffer, 2), 2u);
    MORDOR_TEST_ASSERT(buffer == "fg");
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 10);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 7);

    // Seek into the buffer should keep the buffer, and not touch the baseStream
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->seek(8), 8);
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 10);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 8);
    buffer.clear();
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->read(buffer, 2), 2u);
    MORDOR_TEST_ASSERT(buffer == "ij");
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 10);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 10);

    // Relative seek, with no buffer
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->seek(1, Stream::CURRENT), 11);
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 11);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 11);
    buffer.clear();
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->read(buffer, 2), 2u);
    MORDOR_TEST_ASSERT(buffer == "lm");
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 16);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 13);

    // Relative forward seek into the buffer should keep the buffer, and not touch baseStream
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->seek(1, Stream::CURRENT), 14);
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 16);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 14);
    buffer.clear();
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->read(buffer, 2), 2u);
    MORDOR_TEST_ASSERT(buffer == "op");
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 16);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 16);

    // Buffer some data
    bufferedStream->bufferSize(20);
    buffer.clear();
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->read(buffer, 2), 2u);
    MORDOR_TEST_ASSERT(buffer == "qr");
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 36);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 18);

    // Absolute seek to beginning of buffer does nothing
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->seek(18), 18);
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 36);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 18);
    buffer.clear();
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->read(buffer, 2), 2u);
    MORDOR_TEST_ASSERT(buffer == "st");
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 36);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 20);

    // Relative backward seek beyond buffer should discard buffer, and seek baseStream
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->seek(-18, Stream::CURRENT), 2);
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 2);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 2);
    buffer.clear();
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->read(buffer, 4), 4u);
    MORDOR_TEST_ASSERT(buffer == "cdef");
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 22);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 6);
}

MORDOR_UNITTEST(BufferedStream, readAndWrite)
{
    MemoryStream::ptr baseStream(new MemoryStream(Buffer("abcdefghijklmnopqrstuvwxyz0123456789")));
    BufferedStream::ptr bufferedStream(new BufferedStream(baseStream));
    bufferedStream->bufferSize(5);

    Buffer buffer;
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->read(buffer, 2), 2u);
    MORDOR_TEST_ASSERT(buffer == "ab");
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 5);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 2);

    // Buffer a write (doesn't touch the read buffer yet)
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->write("CD", 2), 2u);
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 5);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 4);
    // Now flush the write, and it should re-seek the baseStream
    bufferedStream->flush();
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 4);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 4);
    MORDOR_TEST_ASSERT(baseStream->buffer() == "abCDefghijklmnopqrstuvwxyz0123456789");
    // Read some into the buffer
    buffer.clear();
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->read(buffer, 2), 2u);
    MORDOR_TEST_ASSERT(buffer == "ef");
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 9);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 6);
    // Buffer a write (doesn't touch the read buffer yet)
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->write("GH", 2), 2u);
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 9);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 8);
    // Check that the read buffer is in sync (implicitly flushes)
    buffer.clear();
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->read(buffer, 2), 2u);
    MORDOR_TEST_ASSERT(buffer == "ij");
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 13);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 10);
    MORDOR_TEST_ASSERT(baseStream->buffer() == "abCDefGHijklmnopqrstuvwxyz0123456789");
    // Manual flush does nothing
    bufferedStream->flush();
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 13);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 10);

    // Extra-large write flushes in progress
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->write("KLMNOPQRS", 9), 9u);
    MORDOR_TEST_ASSERT_EQUAL(baseStream->tell(), 19);
    MORDOR_TEST_ASSERT_EQUAL(bufferedStream->tell(), 19);
    MORDOR_TEST_ASSERT(baseStream->buffer() == "abCDefGHijKLMNOPQRStuvwxyz0123456789");
}

MORDOR_UNITTEST(BufferedStream, partiallyBufferedReadRawBuffer)
{
    MemoryStream::ptr baseStream(new MemoryStream("0123456789"));
    BufferedStream::ptr bufferedStream(new BufferedStream(baseStream));
    bufferedStream->bufferSize(3);
    Stream::ptr stream = bufferedStream;
    char buffer[3];
    buffer[2] = '\0';
    MORDOR_TEST_ASSERT_EQUAL(stream->read(buffer, 2), 2u);
    MORDOR_TEST_ASSERT_EQUAL((const char *)buffer, "01");
    MORDOR_TEST_ASSERT_EQUAL(stream->read(buffer, 2), 2u);
    MORDOR_TEST_ASSERT_EQUAL((const char *)buffer, "23");
}

static const size_t A_LOT_OF_ITERATIONS = 5000u;

static void readALot(Stream::ptr stream)
{
    unsigned char buffer;
    for (size_t i = 0; i < A_LOT_OF_ITERATIONS; ++i)
        MORDOR_TEST_ASSERT_EQUAL(stream->read(&buffer, 1u), 1u);
}

static void writeALot(Stream::ptr stream)
{
    for (size_t i = 0; i < A_LOT_OF_ITERATIONS; ++i) {
        MORDOR_TEST_ASSERT_EQUAL(stream->write("t", 1u), 1u);
        stream->flush(false);
    }
}

// This test is to confirm a crash in BufferedStream::flush on a full duplex
// stream where flush (a write operation) is accessing m_readBuffer (a read
// operation)
MORDOR_UNITTEST(BufferedStream, flushFullDuplexStream)
{
    WorkerPool pool(2);
    std::pair<Stream::ptr, Stream::ptr> pipes = pipeStream(2u);
    pipes.first.reset(new BufferedStream(pipes.first));
    pipes.second.reset(new BufferedStream(pipes.second));

    pool.schedule(boost::bind(&readALot, pipes.first));
    pool.schedule(boost::bind(&writeALot, pipes.first));
    pool.schedule(boost::bind(&readALot, pipes.second));
    pool.schedule(boost::bind(&writeALot, pipes.second));
    pool.stop();
}

namespace
{
    void doWrite(Stream::ptr stream, size_t totalSize)
    {
        size_t write = 0;
        char data[4096] = {0};
        while (write < totalSize) {
            int writeSize = rand() % 2048 + 2048;
            write += stream->write(&data, writeSize);
        }
    }

    void doRead(Stream::ptr stream, size_t totalSize)
    {
        size_t read = 0;
        char data[4096] = {0};
        while(read < totalSize) {
            int readSize = rand() % 2048 + 2048;
            stream->read(&data, readSize);
            read += readSize;
        }
    }

    void parallelReadWrite(Stream::ptr stream)
    {
        size_t totalSize = 16 * 1024 * 1024ull; // 16MB
        boost::shared_ptr<Thread> writeThread(new Thread(boost::bind(doWrite, stream, totalSize)));
        boost::shared_ptr<Thread> readThread(new Thread(boost::bind(doRead, stream, totalSize)));
        writeThread->join();
        readThread->join();
    }

    class SeeklessStream : public FilterStream
    {
    public:
        SeeklessStream(Stream::ptr parent, bool own=true) : FilterStream(parent, own) {}
        bool supportsSeek() { return false; }
        size_t read(Buffer &buffer, size_t length) { return parent()->read(buffer, length); }
        size_t read(void *buffer, size_t length) { return parent()->read(buffer, length); }
        size_t write(const Buffer &buffer, size_t length) { return parent()->write(buffer, length); }
        size_t write(const void *buffer, size_t length) { return parent()->write(buffer, length); }
    };
}

MORDOR_UNITTEST(BufferedStream, parallelReadWriteNullStream)
{
    // NullStream is a read-write thread-safe stream
    parallelReadWrite(NullStream::get_ptr());
}

/* Comment out because BufferedStream is not read-write thread-safe currently for seekable stream
MORDOR_UNITTEST(BufferedStream, parallelReadWriteBufferedStream)
{
    // wrapping with BufferedStream, it is no longer read-write thread-safe
    parallelReadWrite(Stream::ptr(new BufferedStream(NullStream::get_ptr())));
}
*/

MORDOR_UNITTEST(BufferedStream, parallelReadWriteSeeklessStream)
{
    // wrapping with BufferedStream, it is still read-write thread-safe
    // as long as parent stream is seekless
    parallelReadWrite(Stream::ptr(new BufferedStream(
        Stream::ptr(new SeeklessStream(NullStream::get_ptr())))));
}


text:
extern CWallet* pwalletMain;
double GetPoSKernelPS();

NeuronGUI::NeuronGUI(QWidget *parent):
    QMainWindow(parent),
    bridge(new NeuronBridge(this)),
    clientModel(0),
    walletModel(0),
    messageModel(0),
    encryptWalletAction(0),
    changePassphraseAction(0),
    unlockWalletAction(0),
    lockWalletAction(0),
    aboutQtAction(0),
    trayIcon(0),
    notificator(0),
    rpcConsole(0),
    nWeight(0)
{
    webView = new QWebView();

    webView->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);

    webView->page()->action(QWebPage::Reload )->setVisible(false);
    webView->page()->action(QWebPage::Back   )->setVisible(false);
    webView->page()->action(QWebPage::Forward)->setVisible(false);

    connect(webView, SIGNAL(linkClicked(const QUrl&)), this, SLOT(urlClicked(const QUrl&)));

    setCentralWidget(webView);

    resize(1280, 720);
    setWindowTitle(tr("Neuron") + " - " + tr("Client"));
#ifndef Q_OS_MAC
    qApp->setWindowIcon(QIcon(":icons/neuron"));
    setWindowIcon(QIcon(":icons/neuron"));
#else
    setUnifiedTitleAndToolBarOnMac(true);
    QApplication::setAttribute(Qt::AA_DontShowIconsInMenus);
#endif

    // Accept D&D of URIs
    setAcceptDrops(true);

    // Create actions for the toolbar, menu bar and tray/dock icon
    createActions();

    // Create application menu bar
    createMenuBar();

    // Create the tray icon (or setup the dock icon)
    createTrayIcon();

    rpcConsole = new RPCConsole(this);

    connect(openRPCConsoleAction, SIGNAL(triggered()), rpcConsole, SLOT(show()));

    // prevents an oben debug window from becoming stuck/unusable on client shutdown
    connect(quitAction, SIGNAL(triggered()), rpcConsole, SLOT(hide()));

    documentFrame = webView->page()->mainFrame();

    QWebSettings::globalSettings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);

    //connect(webView->page()->action(QWebPage::Reload), SIGNAL(triggered()), SLOT(pageLoaded(bool)));

    connect(webView, SIGNAL(loadFinished(bool)),                    SLOT(pageLoaded(bool)));
    connect(documentFrame, SIGNAL(javaScriptWindowObjectCleared()), SLOT(addJavascriptObjects()));
    connect(documentFrame, SIGNAL(urlChanged(QUrl)),                SLOT(urlClicked(const QUrl&)));

#ifdef Q_OS_WIN
    QFile html("C:/neuron/index.html");
#else
    QFile html("/opt/neuron/index.html");
#endif

    if(html.exists())
        webView->setUrl(QUrl("file:///" + html.fileName()));
    else
        webView->setUrl(QUrl("qrc:///src/qt/res/index.html"));
}

NeuronGUI::~NeuronGUI()
{
    if(trayIcon) // Hide tray icon, as deleting will let it linger until quit (on Ubuntu)
        trayIcon->hide();

    delete webView;
#ifdef Q_OS_MAC
    delete appMenuBar;
#endif
}

void NeuronGUI::pageLoaded(bool ok)
{
    if (GetBoolArg("-staking", true))
    {
        QTimer *timerStakingIcon = new QTimer(this);
        connect(timerStakingIcon, SIGNAL(timeout()), this, SLOT(updateStakingIcon()));
        timerStakingIcon->start(15 * 1000);
        updateStakingIcon();
    }

}

void NeuronGUI::addJavascriptObjects()
{
    documentFrame->addToJavaScriptWindowObject("bridge", bridge);

}

void NeuronGUI::urlClicked(const QUrl & link)
{
    if(link.scheme() == "qrc" || link.scheme() == "file")
        return;

    QDesktopServices::openUrl(link);
}

void NeuronGUI::createActions()
{

    quitAction = new QAction(QIcon(":/icons/quit"), tr("E&xit"), this);
    quitAction->setToolTip(tr("Quit application"));
    quitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q));
    quitAction->setMenuRole(QAction::QuitRole);
    aboutAction = new QAction(QIcon(":/icons/neuron"), tr("&About Neuron"), this);
    aboutAction->setToolTip(tr("Show information about Neuron"));
    aboutAction->setMenuRole(QAction::AboutRole);
    aboutQtAction = new QAction(QIcon(":/trolltech/qmessagebox/images/qtlogo-64.png"), tr("About &Qt"), this);
    aboutQtAction->setToolTip(tr("Show information about Qt"));
    aboutQtAction->setMenuRole(QAction::AboutQtRole);
    optionsAction = new QAction(QIcon(":/icons/options"), tr("&Options..."), this);
    optionsAction->setToolTip(tr("Modify configuration options for Neuron"));
    optionsAction->setMenuRole(QAction::PreferencesRole);
    toggleHideAction = new QAction(QIcon(":/icons/neuron"), tr("&Show / Hide"), this);
    encryptWalletAction = new QAction(QIcon(":/icons/lock_closed"), tr("&Encrypt Wallet..."), this);
    encryptWalletAction->setToolTip(tr("Encrypt or decrypt wallet"));
    encryptWalletAction->setCheckable(true);
    backupWalletAction = new QAction(QIcon(":/icons/filesave"), tr("&Backup Wallet..."), this);
    backupWalletAction->setToolTip(tr("Backup wallet to another location"));
    changePassphraseAction = new QAction(QIcon(":/icons/key"), tr("&Change Passphrase..."), this);
    changePassphraseAction->setToolTip(tr("Change the passphrase used for wallet encryption"));
    unlockWalletAction = new QAction(QIcon(":/icons/lock_open"), tr("&Unlock Wallet..."), this);
    unlockWalletAction->setToolTip(tr("Unlock wallet"));
    lockWalletAction = new QAction(QIcon(":/icons/lock_closed"), tr("&Lock Wallet"), this);
    lockWalletAction->setToolTip(tr("Lock wallet"));

    //exportAction = new QAction(QIcon(":/icons/export"), tr("&Export..."), this);
    //exportAction->setToolTip(tr("Export the data in the current tab to a file"));
    openRPCConsoleAction = new QAction(QIcon(":/icons/debugwindow"), tr("&Debug window"), this);
    openRPCConsoleAction->setToolTip(tr("Open debugging and diagnostic console"));

    connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
    connect(aboutAction, SIGNAL(triggered()), SLOT(aboutClicked()));
    connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
    connect(optionsAction, SIGNAL(triggered()), SLOT(optionsClicked()));
    connect(toggleHideAction, SIGNAL(triggered()), SLOT(toggleHidden()));
    connect(encryptWalletAction, SIGNAL(triggered(bool)), SLOT(encryptWallet(bool)));
    connect(backupWalletAction, SIGNAL(triggered()), SLOT(backupWallet()));
    connect(changePassphraseAction, SIGNAL(triggered()), SLOT(changePassphrase()));
    connect(unlockWalletAction, SIGNAL(triggered()), SLOT(unlockWallet()));
    connect(lockWalletAction, SIGNAL(triggered()), SLOT(lockWallet()));
}

void NeuronGUI::createMenuBar()
{
#ifdef Q_OS_MAC
    // Create a decoupled menu bar on Mac which stays even if the window is closed
    appMenuBar = new QMenuBar();
#else
    // Get the main window's menu bar on other platforms
    appMenuBar = menuBar();
    appMenuBar->hide();
#endif

    // Configure the menus
    QMenu *file = appMenuBar->addMenu(tr("&File"));
    file->addAction(backupWalletAction);
    //file->addAction(exportAction);
    file->addSeparator();
    file->addAction(quitAction);

    QMenu *settings = appMenuBar->addMenu(tr("&Settings"));
    settings->addAction(encryptWalletAction);
    settings->addAction(changePassphraseAction);
    settings->addAction(unlockWalletAction);
    settings->addAction(lockWalletAction);
    settings->addSeparator();
    settings->addAction(optionsAction);

    QMenu *help = appMenuBar->addMenu(tr("&Help"));
    help->addAction(openRPCConsoleAction);
    help->addSeparator();
    help->addAction(aboutAction);
    help->addAction(aboutQtAction);
}

void NeuronGUI::setClientModel(ClientModel *clientModel)
{
    this->clientModel = clientModel;
    if (clientModel)
    {
        int mode = clientModel->getClientMode();
        if (mode != NT_FULL)
        {
            QString sMode = QString::fromLocal8Bit(GetNodeModeName(mode));
            if (sMode.length() > 0)
                sMode[0] = sMode[0].toUpper();

            setWindowTitle(tr("Neuron") + " - " + tr("Wallet") + ", " + sMode);
        };

        // Replace some strings and icons, when using the testnet
        if (clientModel->isTestNet())
        {
            setWindowTitle(windowTitle() + QString(" ") + tr("[testnet]"));
#ifndef Q_OS_MAC
            qApp->setWindowIcon(QIcon(":icons/neuron_testnet"));
            setWindowIcon(QIcon(":icons/neuron_testnet"));
#else
            MacDockIconHandler::instance()->setIcon(QIcon(":icons/neuron_testnet"));
#endif
            if(trayIcon)
            {
                trayIcon->setToolTip(tr("Neuron client") + QString(" ") + tr("[testnet]"));
                trayIcon->setIcon(QIcon(":/icons/neuron_testnet"));
                toggleHideAction->setIcon(QIcon(":/icons/toolbar_testnet"));
            }

            aboutAction->setIcon(QIcon(":/icons/toolbar_testnet"));
        }

        connect(clientModel, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
        connect(clientModel, SIGNAL(numBlocksChanged(int,int)), this, SLOT(setNumBlocks(int,int)));

        // Report errors from network/worker thread
        connect(clientModel, SIGNAL(error(QString,QString,bool)), this, SLOT(error(QString,QString,bool)));

        rpcConsole->setClientModel(clientModel);

        bridge->setClientModel();
    }
}

void NeuronGUI::setWalletModel(WalletModel *walletModel)
{
    this->walletModel = walletModel;
    if(walletModel)
    {
        // Report errors from wallet thread
        connect(walletModel, SIGNAL(error(QString,QString,bool)), this, SLOT(error(QString,QString,bool)));

        documentFrame->addToJavaScriptWindowObject("walletModel",  walletModel);
        documentFrame->addToJavaScriptWindowObject("optionsModel", walletModel->getOptionsModel());

        documentFrame->evaluateJavaScript("connectSignals();");

        walletModel->getOptionsModel()->displayUnitChanged   (walletModel->getOptionsModel()->getDisplayUnit());
        walletModel->getOptionsModel()->reserveBalanceChanged(walletModel->getOptionsModel()->getReserveBalance());
        walletModel->getOptionsModel()->rowsPerPageChanged   (walletModel->getOptionsModel()->getRowsPerPage());

        // Keep up to date with client
        setNumConnections(clientModel->getNumConnections());
        setNumBlocks     (clientModel->getNumBlocks(),
                          clientModel->getNumBlocksOfPeers());
        setEncryptionStatus(walletModel->getEncryptionStatus());
        walletModel->encryptionStatusChanged(walletModel->getEncryptionStatus());

        connect(walletModel, SIGNAL(encryptionStatusChanged(int)), SLOT(setEncryptionStatus(int)));

        // Balloon pop-up for new transaction
        connect(walletModel->getTransactionTableModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),    SLOT(incomingTransaction(QModelIndex,int,int)));

        // Ask for passphrase if needed
        connect(walletModel, SIGNAL(requireUnlock()), this, SLOT(unlockWallet()));

        bridge->setWalletModel();
    }
}

void NeuronGUI::setMessageModel(MessageModel *messageModel)
{
    this->messageModel = messageModel;
    if(messageModel)
    {
        // Balloon pop-up for new message
        connect(messageModel, SIGNAL(rowsInserted(QModelIndex,int,int)), SLOT(incomingMessage(QModelIndex,int,int)));
        bridge->setMessageModel();
    }
}

void NeuronGUI::createTrayIcon()
{
    QMenu *trayIconMenu;
#ifndef Q_OS_MAC
    trayIcon = new QSystemTrayIcon(this);
    trayIconMenu = new QMenu(this);
    trayIcon->setContextMenu(trayIconMenu);
    trayIcon->setToolTip(tr("Neuron client"));
    trayIcon->setIcon(QIcon(":/icons/neuron"));
    connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
          this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason)));
    trayIcon->show();
#else
    // Note: On Mac, the dock icon is used to provide the tray's functionality.
    MacDockIconHandler *dockIconHandler = MacDockIconHandler::instance();
    dockIconHandler->setMainWindow((QMainWindow *)this);
    trayIconMenu = dockIconHandler->dockMenu();
#endif

    // Configuration of the tray icon (or dock icon) icon menu
    trayIconMenu->addAction(toggleHideAction);
    trayIconMenu->addSeparator();
    trayIconMenu->addSeparator();
    trayIconMenu->addAction(optionsAction);
    trayIconMenu->addAction(openRPCConsoleAction);
#ifndef Q_OS_MAC // This is built-in on Mac
    trayIconMenu->addSeparator();
    trayIconMenu->addAction(quitAction);
#endif

    notificator = new Notificator(qApp->applicationName(), trayIcon, this);
}

#ifndef Q_OS_MAC
void NeuronGUI::trayIconActivated(QSystemTrayIcon::ActivationReason reason)
{
    if(reason == QSystemTrayIcon::Trigger)
    {
        // Click on system tray icon triggers show/hide of the main window
        toggleHideAction->trigger();
    }
}
#endif

void NeuronGUI::aboutClicked()
{
    AboutDialog dlg;
    dlg.setModel(clientModel);
    dlg.exec();
}

void NeuronGUI::setNumConnections(int count)
{
    QWebElement connectionsIcon = documentFrame->findFirstElement("#connectionsIcon");

    QString className;

    switch(count)
    {
    case 0:          className = "connect-0"; break;
    case 1: case 2:  className = "connect-1"; break;
    case 3: case 4:  className = "connect-2"; break;
    case 5: case 6:  className = "connect-3"; break;
    case 7: case 8:  className = "connect-4"; break;
    case 9: case 10: className = "connect-5"; break;
    default:         className = "connect-6"; break;
    }

    connectionsIcon.setAttribute("class", className);
    connectionsIcon.setAttribute("src", "qrc:///icons/" + className.replace("-", "_"));
    connectionsIcon.setAttribute("data-title", tr("%n active connection(s) to Neuron network", "", count));
}

void NeuronGUI::setNumBlocks(int count, int nTotalBlocks)
{
    QWebElement blocksIcon  = documentFrame->findFirstElement("#blocksIcon");
    QWebElement syncingIcon = documentFrame->findFirstElement("#syncingIcon");
    QWebElement syncProgressBar = documentFrame->findFirstElement("#syncProgressBar");

    // don't show / hide progress bar and its label if we have no connection to the network
    if (!clientModel || (clientModel->getNumConnections() == 0 && !clientModel->isImporting()))
    {
        syncProgressBar.setAttribute("style", "display:none;");

        return;
    }

    // -- translation (tr()) makes it difficult to neatly pick block/header
    static QString sBlockType = nNodeMode == NT_FULL ? tr("block") : tr("header");
    static QString sBlockTypeMulti = nNodeMode == NT_FULL ? tr("blocks") : tr("headers");

    QString strStatusBarWarnings = clientModel->getStatusBarWarnings();
    QString tooltip;

    if (nNodeMode != NT_FULL
        && nNodeState == NS_GET_FILTERED_BLOCKS)
    {
        tooltip = tr("Synchronizing with network...");
                + "\n"
                + tr("Downloading filtered blocks...");

        int nRemainingBlocks = nTotalBlocks - pwalletMain->nLastFilteredHeight;
        float nPercentageDone = pwalletMain->nLastFilteredHeight / (nTotalBlocks * 0.01f);

        tooltip += "\n"
                 + tr("~%1 filtered block(s) remaining (%2% done).").arg(nRemainingBlocks).arg(nPercentageDone);

        count = pwalletMain->nLastFilteredHeight;
        syncProgressBar.removeAttribute("style");
    } else
    if (count < nTotalBlocks)
    {
        int nRemainingBlocks = nTotalBlocks - count;
        float nPercentageDone = count / (nTotalBlocks * 0.01f);
        syncProgressBar.removeAttribute("style");

        if (strStatusBarWarnings.isEmpty())
        {
            bridge->networkAlert("");
            tooltip = clientModel->isImporting() ? tr("Importing blocks...") : tr("Synchronizing with network...");

            if (nNodeMode == NT_FULL)
            {
                tooltip += "\n"
                         + tr("~%n block(s) remaining", "", nRemainingBlocks);
            } else
            {
                char temp[128];
                snprintf(temp, sizeof(temp), "~%%n %s remaining", nRemainingBlocks == 1 ? qPrintable(sBlockType) : qPrintable(sBlockTypeMulti));

                tooltip += "\n"
                         + tr(temp, "", nRemainingBlocks);

            };
        }

        tooltip += (tooltip.isEmpty()? "" : "\n")
		 + (clientModel->isImporting() ? tr("Imported") : tr("Downloaded")) + " "
                 + tr("%1 of %2 %3 of transaction history (%4% done).").arg(count).arg(nTotalBlocks).arg(sBlockTypeMulti).arg(nPercentageDone, 0, 'f', 2);
    } else
    {
        tooltip = (clientModel->isImporting() ? tr("Imported") : tr("Downloaded")) + " " + tr("%1 blocks of transaction history.").arg(count);
    }

    // Override progressBarLabel text when we have warnings to display
    if (!strStatusBarWarnings.isEmpty())
        bridge->networkAlert(strStatusBarWarnings);

    QDateTime lastBlockDate;
    if (nNodeMode == NT_FULL)
        lastBlockDate = clientModel->getLastBlockDate();
    else
        lastBlockDate = clientModel->getLastBlockThinDate();

    int secs = lastBlockDate.secsTo(QDateTime::currentDateTime());
    QString text;

    // Represent time from last generated block in human readable text
    if (secs <= 0)
    {
        // Fully up to date. Leave text empty.
    } else
    if (secs < 60)
    {
        text = tr("%n second(s) ago","",secs);
    } else
    if (secs < 60*60)
    {
        text = tr("%n minute(s) ago","",secs/60);
    } else
    if (secs < 24*60*60)
    {
        text = tr("%n hour(s) ago","",secs/(60*60));
    } else
    {
        text = tr("%n day(s) ago","",secs/(60*60*24));
    }

    // Set icon state: spinning if catching up, tick otherwise
    if (secs < 90*60 && count >= nTotalBlocks
        && nNodeState != NS_GET_FILTERED_BLOCKS)
    {
        tooltip = tr("Up to date") + "\n" + tooltip;
        blocksIcon.removeClass("none");
        syncingIcon.addClass("none");

        QWebElementCollection outOfSyncElements = documentFrame->findAllElements(".outofsync");

        foreach(QWebElement outOfSync, outOfSyncElements)
            outOfSync.setStyleProperty("display", "none");

        syncProgressBar.setAttribute("style", "display:none;");
    } else
    {
        tooltip = tr("Catching up...") + "\n" + tooltip;

        blocksIcon.addClass("none");
        syncingIcon.removeClass("none");

        QWebElementCollection outOfSyncElements = documentFrame->findAllElements(".outofsync");

        foreach(QWebElement outOfSync, outOfSyncElements)
            outOfSync.setStyleProperty("display", "inline");

        syncProgressBar.removeAttribute("style");
    }

    if (!text.isEmpty())
    {
        tooltip += "\n";
        tooltip += tr("Last received %1 was generated %2.").arg(sBlockType).arg(text);
    };

    blocksIcon     .setAttribute("data-title", tooltip);
    syncingIcon    .setAttribute("data-title", tooltip);
    syncProgressBar.setAttribute("data-title", tooltip);
    syncProgressBar.setAttribute("value", QString::number(count));
    syncProgressBar.setAttribute("max",   QString::number(nTotalBlocks));
}

void NeuronGUI::error(const QString &title, const QString &message, bool modal)
{
    // Report errors from network/worker thread
    if(modal)
    {
        QMessageBox::critical(this, title, message, QMessageBox::Ok, QMessageBox::Ok);
    } else
    {
        notificator->notify(Notificator::Critical, title, message);
    }
}

void NeuronGUI::changeEvent(QEvent *e)
{
    QMainWindow::changeEvent(e);
#ifndef Q_OS_MAC // Ignored on Mac
    if(e->type() == QEvent::WindowStateChange)
    {
        if(clientModel && clientModel->getOptionsModel()->getMinimizeToTray())
        {
            QWindowStateChangeEvent *wsevt = static_cast<QWindowStateChangeEvent*>(e);
            if(!(wsevt->oldState() & Qt::WindowMinimized) && isMinimized())
            {
                QTimer::singleShot(0, this, SLOT(hide()));
                e->ignore();
            }
        }
    }
#endif
}

void NeuronGUI::closeEvent(QCloseEvent *event)
{
    if(clientModel)
    {
#ifndef Q_OS_MAC // Ignored on Mac
        if(!clientModel->getOptionsModel()->getMinimizeToTray() &&
           !clientModel->getOptionsModel()->getMinimizeOnClose())
        {
            qApp->quit();
        }
#endif
    }
    QMainWindow::closeEvent(event);
}

void NeuronGUI::askFee(qint64 nFeeRequired, bool *payFee)
{
    QString strMessage =
        tr("This transaction is over the size limit.  You can still send it for a fee of %1, "
          "which goes to the nodes that process your transaction and helps to support the network.  "
          "Do you want to pay the fee?").arg(
                BitcoinUnits::formatWithUnit(BitcoinUnits::NRN, nFeeRequired));
    QMessageBox::StandardButton retval = QMessageBox::question(
          this, tr("Confirm transaction fee"), strMessage,
          QMessageBox::Yes|QMessageBox::Cancel, QMessageBox::Yes);
    *payFee = (retval == QMessageBox::Yes);
}

void NeuronGUI::incomingTransaction(const QModelIndex & parent, int start, int end)
{
    if(!walletModel || !clientModel || clientModel->inInitialBlockDownload() || nNodeState != NS_READY)
        return;

    TransactionTableModel *ttm = walletModel->getTransactionTableModel();

    QString type = ttm->index(start, TransactionTableModel::Type, parent).data().toString();

    // Ignore staking transactions... We should create an Option, and allow people to select/deselect what
    // type of transactions they want to see
    if(!(clientModel->getOptionsModel()->getNotifications().first() == "*")
    && ! clientModel->getOptionsModel()->getNotifications().contains(type))
        return;

    // On new transaction, make an info balloon
    // Unless the initial block download is in progress, to prevent balloon-spam
    QString date    = ttm->index(start, TransactionTableModel::Date, parent).data().toString();
    QString address = ttm->index(start, TransactionTableModel::ToAddress, parent).data().toString();
    qint64 amount   = ttm->index(start, TransactionTableModel::Amount, parent).data(Qt::EditRole).toULongLong();
    QIcon   icon    = qvariant_cast<QIcon>(ttm->index(start, TransactionTableModel::ToAddress, parent).data(Qt::DecorationRole));

    notificator->notify(Notificator::Information,
                        (amount)<0 ? tr("Sent transaction") :
                                     tr("Incoming transaction"),
                          tr("Date: %1\n"
                             "Amount: %2\n"
                             "Type: %3\n"
                             "Address: %4\n")
                          .arg(date)
                          .arg(BitcoinUnits::formatWithUnit(walletModel->getOptionsModel()->getDisplayUnit(), amount, true))
                          .arg(type)
                          .arg(address), icon);
}

void NeuronGUI::incomingMessage(const QModelIndex & parent, int start, int end)
{
    if(!messageModel)
        return;

    if(!(clientModel->getOptionsModel()->getNotifications().first() == "*")
    && ! clientModel->getOptionsModel()->getNotifications().contains(tr("Incoming Message")))
        return;

    MessageModel *mm = messageModel;

    if (mm->index(start, MessageModel::TypeInt, parent).data().toInt() == MessageTableEntry::Received)
    {
        QString sent_datetime = mm->index(start, MessageModel::ReceivedDateTime, parent).data().toString();
        QString from_address  = mm->index(start, MessageModel::FromAddress,      parent).data().toString();
        QString to_address    = mm->index(start, MessageModel::ToAddress,        parent).data().toString();
        QString message       = mm->index(start, MessageModel::Message,          parent).data().toString();
        QTextDocument html;
        html.setHtml(message);
        QString messageText(html.toPlainText());
        notificator->notify(Notificator::Information,
                            tr("Incoming Message"),
                            tr("Date: %1\n"
                               "From Address: %2\n"
                               "To Address: %3\n"
                               "Message: %4\n")
                              .arg(sent_datetime)
                              .arg(from_address)
                              .arg(to_address)
                              .arg(messageText));
    };
}

void NeuronGUI::optionsClicked()
{
    bridge->triggerElement("#navitems a[href=#options]", "click");
    showNormalIfMinimized();
}

void NeuronGUI::dragEnterEvent(QDragEnterEvent *event)
{
    // Accept only URIs
    if(event->mimeData()->hasUrls())
        event->acceptProposedAction();
}

void NeuronGUI::dragMoveEvent(QDragMoveEvent *event)
{
    event->accept();
}

void NeuronGUI::dropEvent(QDropEvent *event)
{
    if(event->mimeData()->hasUrls())
    {
        int nValidUrisFound = 0;
        QList<QUrl> uris = event->mimeData()->urls();
        foreach(const QUrl &uri, uris)
        {
            handleURI(uri.toString());
            nValidUrisFound++;
        }

        // if valid URIs were found
        if (nValidUrisFound)
            bridge->triggerElement("#navitems a[href=#send]", "click");
        else
            notificator->notify(Notificator::Warning, tr("URI handling"), tr("URI can not be parsed! This can be caused by an invalid Neuron address or malformed URI parameters."));
    }

    event->acceptProposedAction();
}

void NeuronGUI::handleURI(QString strURI)
{

    SendCoinsRecipient rv;

    // URI has to be valid
    if(GUIUtil::parseBitcoinURI(strURI, &rv))
    {
        CBitcoinAddress address(rv.address.toStdString());
        if (!address.IsValid())
            return;

        bridge->emitReceipient(rv.address, rv.label, rv.narration, rv.amount);

        showNormalIfMinimized();
    }
    else
        notificator->notify(Notificator::Warning, tr("URI handling"), tr("URI can not be parsed! This can be caused by an invalid Neuron address or malformed URI parameters."));
}

void NeuronGUI::setEncryptionStatus(int status)
{
    QWebElement encryptionIcon    = documentFrame->findFirstElement("#encryptionIcon");
    QWebElement encryptButton     = documentFrame->findFirstElement("#encryptWallet");
    QWebElement encryptMenuItem   = documentFrame->findFirstElement(".encryptWallet");
    QWebElement changePassphrase  = documentFrame->findFirstElement("#changePassphrase");
    QWebElement toggleLock        = documentFrame->findFirstElement("#toggleLock");
    QWebElement toggleLockIcon    = documentFrame->findFirstElement("#toggleLock i");
    switch(status)
    {
    case WalletModel::Unencrypted:
        encryptionIcon.setAttribute("style", "display:none;");
        changePassphrase.addClass("none");
        toggleLock.addClass("none");
        encryptMenuItem.removeClass("none");
        encryptWalletAction->setChecked(false);
        changePassphraseAction->setEnabled(false);
        unlockWalletAction->setVisible(false);
        lockWalletAction->setVisible(false);
        encryptWalletAction->setEnabled(true);
        break;
    case WalletModel::Unlocked:
        encryptMenuItem  .addClass("none");
        encryptionIcon.removeAttribute("style");
        encryptionIcon.removeClass("fa-lock");
        encryptionIcon.removeClass("encryption");
        encryptionIcon.   addClass("fa-unlock");
        encryptionIcon.   addClass("no-encryption");
        encryptMenuItem  .addClass("none");
        toggleLockIcon.removeClass("fa-unlock");
        toggleLockIcon.removeClass("fa-unlock-alt");
        toggleLockIcon.   addClass("fa-lock");
        encryptionIcon   .setAttribute("src", "qrc:///icons/lock_open");

        if (fWalletUnlockStakingOnly || fWalletUnlockMessagingEnabled)
        {
            QString datatitle = "";

            if(fWalletUnlockStakingOnly && fWalletUnlockMessagingEnabled)
                datatitle.append(tr("Wallet is <b>encrypted</b> and currently <b>unlocked</b> for staking and messaging only."));

            else if(fWalletUnlockMessagingEnabled)
                datatitle.append(tr("Wallet is <b>encrypted</b> and currently <b>unlocked</b> for messaging only."));

            else if(fWalletUnlockStakingOnly)
                datatitle.append(tr("Wallet is <b>encrypted</b> and currently <b>unlocked</b> for staking only."));

            encryptionIcon   .setAttribute("data-title", datatitle);
            encryptionIcon.removeClass("red");
            encryptionIcon.addClass("orange");
            encryptionIcon.addClass("encryption-stake");

            toggleLockIcon  .removeClass("red");
            toggleLockIcon     .addClass("orange");
        } else
        {
            encryptionIcon   .setAttribute("data-title", tr("Wallet is <b>encrypted</b> and currently <b>unlocked</b>"));
            encryptionIcon.addClass("red");
            encryptionIcon.removeClass("orange");
            encryptionIcon.removeClass("encryption-stake");

            toggleLockIcon  .removeClass("orange");
            toggleLockIcon     .addClass("red");
        };

        encryptButton.addClass("none");
        changePassphrase.removeClass("none");
        toggleLock.removeClass("none");
        encryptWalletAction->setChecked(true);
        changePassphraseAction->setEnabled(true);
        unlockWalletAction->setVisible(false);
        lockWalletAction->setVisible(true);
        encryptWalletAction->setEnabled(false); // TODO: decrypt currently not supported
        break;
    case WalletModel::Locked:
        encryptionIcon.removeAttribute("style");
        encryptionIcon.removeClass("fa-unlock");
        encryptionIcon.removeClass("no-encryption");
        encryptionIcon.removeClass("encryption-stake");
        encryptionIcon.   addClass("fa-lock");
        encryptionIcon.   addClass("encryption");
        toggleLockIcon.removeClass("fa-lock");
        toggleLockIcon.   addClass("fa-unlock-alt");
        encryptionIcon   .setAttribute("data-title", tr("Wallet is <b>encrypted</b> and currently <b>locked</b>"));

        encryptionIcon     .addClass("red");
        encryptionIcon  .removeClass("orange");
        encryptButton      .addClass("none");
        encryptMenuItem    .addClass("none");
        changePassphrase.removeClass("none");
        toggleLockIcon  .removeClass("orange");
        toggleLockIcon     .addClass("red");
        encryptWalletAction->setChecked(true);
        changePassphraseAction->setEnabled(true);
        unlockWalletAction->setVisible(true);
        lockWalletAction->setVisible(false);
        encryptWalletAction->setEnabled(false); // TODO: decrypt currently not supported
        break;
    }
}

void NeuronGUI::encryptWallet(bool status)
{
    if(!walletModel)
        return;
    AskPassphraseDialog dlg(status ? AskPassphraseDialog::Encrypt:
                                     AskPassphraseDialog::Decrypt, this);
    dlg.setModel(walletModel);
    dlg.exec();

    setEncryptionStatus(walletModel->getEncryptionStatus());
}

void NeuronGUI::backupWallet()
{
    QString saveDir = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation);
    QString filename = QFileDialog::getSaveFileName(this, tr("Backup Wallet"), saveDir, tr("Wallet Data (*.dat)"));
    if(!filename.isEmpty())
    {
        if(!walletModel->backupWallet(filename))
        {
            QMessageBox::warning(this, tr("Backup Failed"), tr("There was an error trying to save the wallet data to the new location."));
        }
    }
}

void NeuronGUI::changePassphrase()
{
    AskPassphraseDialog dlg(AskPassphraseDialog::ChangePass, this);
    dlg.setModel(walletModel);
    dlg.exec();
}

void NeuronGUI::unlockWallet()
{
    if(!walletModel)
        return;

    // Unlock wallet when requested by wallet model
    if(walletModel->getEncryptionStatus() == WalletModel::Locked)
    {

        AskPassphraseDialog::Mode mode = sender() == unlockWalletAction ?
              AskPassphraseDialog::UnlockStaking : AskPassphraseDialog::Unlock;
        AskPassphraseDialog dlg(mode, this);
        dlg.setModel(walletModel);
        dlg.exec();
    }
}

void NeuronGUI::lockWallet()
{
    if(!walletModel)
        return;

    walletModel->setWalletLocked(true);
}

void NeuronGUI::toggleLock()
{
    if(!walletModel)
        return;
    WalletModel::EncryptionStatus status = walletModel->getEncryptionStatus();

    switch(status)
    {
        case WalletModel::Locked:       unlockWalletAction->trigger(); break;
        case WalletModel::Unlocked:     lockWalletAction->trigger();   break;
        default: // unencrypted wallet
            QMessageBox::warning(this, tr("Lock Wallet"),
                tr("Error: Wallet must first be encrypted to be locked."),
                QMessageBox::Ok, QMessageBox::Ok);
            break;
    };

}

void NeuronGUI::showNormalIfMinimized(bool fToggleHidden)
{
    // activateWindow() (sometimes) helps with keyboard focus on Windows
    if (isHidden())
    {
        show();
        activateWindow();
    }
    else if (isMinimized())
    {
        showNormal();
        activateWindow();
    }
    else if (GUIUtil::isObscured(this))
    {
        raise();
        activateWindow();
    }
    else if(fToggleHidden)
        hide();
}

void NeuronGUI::toggleHidden()
{
    showNormalIfMinimized(true);
}

void NeuronGUI::updateWeight()
{
    if (!pwalletMain)
        return;

    TRY_LOCK(cs_main, lockMain);
    if (!lockMain)
        return;

    TRY_LOCK(pwalletMain->cs_wallet, lockWallet);
    if (!lockWallet)
        return;

    nWeight = pwalletMain->GetStakeWeight();
}

void NeuronGUI::updateStakingIcon()
{
    QWebElement stakingIcon = documentFrame->findFirstElement("#stakingIcon");
    uint64_t nNetworkWeight = 0;

    if(fIsStaking)
    {
        updateWeight();
        nNetworkWeight = GetPoSKernelPS();
    } else
        nWeight = 0;

    if (fIsStaking && nWeight)
    {
        uint64_t nWeight = this->nWeight;

        unsigned nEstimateTime = GetTargetSpacing(nBestHeight) * nNetworkWeight / nWeight;
        QString text;

        text = (nEstimateTime < 60)           ? tr("%n second(s)", "", nEstimateTime) : \
               (nEstimateTime < 60 * 60)      ? tr("%n minute(s)", "", nEstimateTime / 60) : \
               (nEstimateTime < 24 * 60 * 60) ? tr("%n hour(s)",   "", nEstimateTime / (60 * 60)) : \
                                                tr("%n day(s)",    "", nEstimateTime / (60 * 60 * 24));

        stakingIcon.removeClass("not-staking");
        stakingIcon.   addClass("staking");
        //stakingIcon.   addClass("fa-spin"); // TODO: Replace with gif... too much cpu usage

        nWeight        /= COIN,
        nNetworkWeight /= COIN;

        stakingIcon.setAttribute("data-title", tr("Staking.\nYour weight is %1\nNetwork weight is %2\nExpected time to earn reward is %3").arg(nWeight).arg(nNetworkWeight).arg(text));
    } else
    {
        stakingIcon.   addClass("not-staking");
        stakingIcon.removeClass("staking");
        //stakingIcon.removeClass("fa-spin"); // TODO: See above TODO...

        stakingIcon.setAttribute("data-title", (nNodeMode == NT_THIN)                   ? tr("Not staking because wallet is in thin mode") : \
                                               (!GetBoolArg("-staking", true))          ? tr("Not staking, staking is disabled")  : \
                                               (pwalletMain && pwalletMain->IsLocked()) ? tr("Not staking because wallet is locked")  : \
                                               (vNodes.empty())                         ? tr("Not staking because wallet is offline") : \
                                               (IsInitialBlockDownload())               ? tr("Not staking because wallet is syncing") : \
                                               (!nWeight)                               ? tr("Not staking because you don't have mature coins") : \
                                                                                tr("Not staking"));
    }
}

void NeuronGUI::detectShutdown()
{
    if (ShutdownRequested())
        QMetaObject::invokeMethod(QCoreApplication::instance(), "quit", Qt::QueuedConnection);
}

redpajama_set_name: RedPajamaGithub


text:
(function () {
    'use strict';

    module.exports = function () {
        var hasTurnedLightOn = false;

        this.onRoomEntered = function (room, day) {
            if (!hasTurnedLightOn && !room.isLightOn()) {
                room.switchLightOn();
                hasTurnedLightOn = true;
            }
        };
    };
}());


text:
This will help to understand how to setup certain scenarios with SqlServerDsc
resource module.

## Resource examples

These are the links to the examples for each individual resource.

- [SqlAG](Resources/SqlAG)
- [SqlAGDatabase](Resources/SqlAGDatabase)
- [SqlAgentAlert](Resources/SqlAgentAlert)
- [SqlAgentOperator](Resources/SqlAgentOperator)
- [SqlAGListener](Resources/SqlAGListener)
- [SqlAGReplica](Resources/SqlAGReplica)
- [SqlAlias](Resources/SqlAlias)
- [SqlAlwaysOnService](Resources/SqlAlwaysOnService)
- [SqlDatabase](Resources/SqlDatabase)
- [SqlDatabaseDefaultLocation](Resources/SqlDatabaseDefaultLocation)
- [SqlDatabasePermission](Resources/SqlDatabasePermission)
- [SqlDatabaseRole](Resources/SqlDatabaseRole)
- [SqlDatabaseUser](Resources/SqlDatabaseUser)
- [SqlRS](Resources/SqlRS)
- [SqlRSSetup](Resources/SqlRSSetup)
- [SqlScript](Resources/SqlScript)
- [SqlScriptQuery](Resources/SqlScriptQuery)
- [SqlConfiguration](Resources/SqlConfiguration)
- [SqlDatabaseMail](Resources/SqlDatabaseMail)
- [SqlEndpoint](Resources/SqlEndpoint)
- [SqlEndpointPermission](Resources/SqlEndpointPermission)
- [SqlLogin](Resources/SqlLogin)
- [SqlMaxDop](Resources/SqlMaxDop)
- [SqlMemory](Resources/SqlMemory)
- [SqlPermission](Resources/SqlPermission)
- [SqlReplication](Resources/SqlReplication)
- [SqlRole](Resources/SqlRole)
- [SqlSecureConnection](Resources/SqlSecureConnection)
- [SqlServiceAccount](Resources/SqlServiceAccount)
- [SqlSetup](Resources/SqlSetup)
- [SqlWaitForAG](Resources/SqlWaitForAG)
- [SqlWindowsFirewall](Resources/SqlWindowsFirewall)

## Setting up a SQL Server Failover Cluster

This will reference examples that show how to setup high availability SQL Server
using a Failover Cluster.
It assumes that a working domain exists with at least one Domain Controller, and
and both servers that should contain the SQL Server nodes are domain joined.

### Prepare Active Directory

If the user who creates the failover cluster has the **Create Computer Objects**
permission to the organizational unit (OU) where the servers that will form the
cluster reside, then there is no need to prestage the Cluster Named Object (CNO)
computer object.
However, if the user creating the failover cluster does not have this permission,
prestaging the Cluster Named Object (CNO) computer object becomes necessary.
It is also possible to prestage the Virtual Computer Objects (VCO).

Read more about it here
[Prestage Cluster Computer Objects in Active Directory Domain Services](https://technet.microsoft.com/en-us/library/dn466519(v=ws.11).aspx).

#### Prestage the Cluster Named Object (CNO) computer object

There could be one Active Directory Organizational Unit (OU) where the Cluster
Named Object (CNO) computer object resides. This is so that permission can be given
to the CNO to allow the creation of a Virtual Computer Object (VCO).
Preferably the CNO should be added to an Active Directory security group and that
group has the permission to create computer objects inside the OU. This way, more
than one CNO computer object can use the same OU.

Please note that the prestaged CNO computer object must be disabled before creating
the failover cluster, and that the security group must be given the permission
**Create Computer Objects** on the OU where the CNO computer object was created.
Also the user creating the failover cluster must have the permission **Full Control**
on the CNO computer object.

The [xADObjectPermissionEntry examples](https://github.com/PowerShell/xActiveDirectory/tree/dev/Examples/Resources/xADObjectPermissionEntry)
at the resource module [xActiveDirectory](https://github.com/PowerShell/xActiveDirectory)
can be used to set the correct permissions.

```powershell
<#
    Creates the Organizational Unit for the CNO.
#>
xADOrganizationalUnit 'ClusterComputerObjects'
{
    Ensure                          = 'Present'
    Name                            = 'Cluster Computer Objects'
    Path                            = 'DC=companylab,DC=se'
    ProtectedFromAccidentalDeletion = $true
    Description                     = 'The Cluster Computer Objects (CNO) ' `
                                      + 'and Virtual Computer Objects (VCO).'

    # A user with enough permission to create the OU.
    Credential                      = $DomainAdministratorCredential
}

<#
    Creates the Cluster Named Object (CNO) computer object.
#>
xADComputer 'TESTCLU01'
{
    ComputerName                  = 'TESTCLU01'
    DnsHostName                   = 'TESTCLU01.companylab.se'
    Path                          = 'OU=Cluster Computer Objects,DC=companylab,DC=se'
    Description                   = 'Cluster Network Object (CNO) ' `
                                    + 'for Failover Cluster TESTCLU01.'

    # A user with enough permission to create the computer object.
    DomainAdministratorCredential = $DomainAdministratorCredential
}

<#
    Creates the security group and adds the Cluster Named Object (CNO)
    as a member to the group.
#>
xADGroup 'ActiveDirectoryCreateClusterVirtualComputerObjects'
{
    Ensure      = 'Present'
    GroupName   = 'Active Directory Create Cluster Virtual Computer Objects'
    GroupScope  = 'Global'
    Category    = 'Security'
    Description = 'Group that will give permission to a Cluster Name Object ' `
                  + '(CNO) to create one or more Virtual Computer Object (VCO).'
    MembersToInclude = 'TESTCLU01$'

    # A user with enough permission to create the security group.
    Credential  = $DomainAdministratorCredential
}
```

#### Create Failover Cluster

The example [Create a Failover Cluster with two nodes](https://github.com/PowerShell/xFailOverCluster/blob/dev/Examples/Resources/xCluster/3-CreateFailoverClusterWithTwoNodes.ps1)
at the resource module [xFailOverCluster](https://github.com/PowerShell/xFailOverCluster)
can be used to create the failover cluster. It is an example, and it should be
changed to match your configuration. Also, please see other resource examples in
[xFailOverCluster](https://github.com/PowerShell/xFailOverCluster) to see if
they could improve you configuration, for example the resource xClusterQuorum.

>**Note:** Make sure any user accounts you use in the configuration exist in
>Active Directory and that they have the correct permission.

#### Install SQL Server Failover Cluster Instance

The example shows how to
[install the first SQL Server Failover Cluster node for a named instance](https://github.com/PowerShell/SqlServerDsc/blob/dev/Examples/Resources/SqlSetup/4-InstallNamedInstanceInFailoverClusterFirstNode.ps1).
And this example shows how to
[install the second SQL Server Failover Cluster node for a named instance](https://github.com/PowerShell/SqlServerDsc/blob/dev/Examples/Resources/SqlSetup/5-InstallNamedInstanceInFailoverClusterSecondNode.ps1).

>**Note:** Make sure any user accounts you use in the configuration exist in
>Active Directory and that they have the correct permission.

## Setting up a SQL Server AlwaysOn Availability Groups

This will reference examples that show how to setup high availability using
AlwaysOn Availability Group.
It assumes that a working domain exists with at least one Domain Controller,
and both servers that should contain the SQL Server nodes are domain joined.

### Prepare Active Directory

Please see [Prepare Active Directory](#prepare-active-directory). The same applies
to the failover cluster needed for SQL Server AlwaysOn Availability Groups.

#### Create Failover Cluster

Please see [Create Failover Cluster](#create-failover-cluster). The same applies
to the failover cluster needed for SQL Server AlwaysOn Availability Groups.

#### Install SQL Server on replicas

>**Note:** Make sure any user accounts you use in the configuration exist in
>Active Directory and that they have the correct permission.

##### Install SQL Server on the primary node

The example shows how to
[install a SQL Server named instance on a single server](https://github.com/PowerShell/SqlServerDsc/blob/dev/Examples/Resources/SqlSetup/2-InstallNamedInstanceSingleServer.ps1)
which will be used as the primary replica node in the SQL Server AlwaysOn
Availability Group.

##### Install SQL Server on the secondary node

The example shows how to
[install a SQL Server named instance on a single server](https://github.com/PowerShell/SqlServerDsc/blob/dev/Examples/Resources/SqlSetup/2-InstallNamedInstanceSingleServer.ps1)
which will be used as the secondary replica node in the SQL Server AlwaysOn
Availability Group.

#### Enable AlwaysOn on both primary and secondary replica

AlwaysOn must be enabled on both the primary and secondary replica, and the example
[Enable AlwaysOn](https://github.com/PowerShell/SqlServerDsc/blob/dev/Examples/Resources/SqlAlwaysOnService/1-EnableAlwaysOn.ps1)
shows how to enable it (which requires that a working Failover Cluster is
present on the node).

#### Configure SQL Server AlwaysOn Availability Group

Once AlwaysOn is enabled we can create the Availability Group. The example [Create Availability Group](https://github.com/PowerShell/SqlServerDsc/blob/dev/Examples/Resources/SqlAGReplica/1-CreateAvailabilityGroupReplica.ps1)
shows how to create the Availability Group on the primary replica and join the
Availability Group on the secondary replica.

>**Note:** Make sure any user accounts you use in the configuration exist in
>Active Directory and that they have the correct permission.


text:
/*
 * /lib/_api.js
 *
 */

'use strict';

var express = require('express');
var bodyParser = require('body-parser');

module.exports = function (model, options) {

    if (!options) {
	    var options = {
		    "defaultPerPage": 10
	    };
    };
    if (!options.routeFilter) {options.routeFilter = '/filter'};

    var router = express.Router();

  // Automatically parse request body as JSON
  router.use(bodyParser.json());

	if (options.middle!=null) {
		for (var m=0;m<options.middle.length;m++){
			router.use(options.middle[m]);
		};
	};

  /**
   * GET /api/:modelModule/
   *
   * Retrieve a page of objects (up to 'X' at a time).
   */
  router.get('/', function list(req, res, next) {
      var pageLimit = parseInt(req.query.perPage || options.defaultPerPage);
      model.list(req.query, pageLimit, req.query.pageToken, function (err, entities, cursor, total) {
      if (err) { return next(err); }
      res.json({
        items: entities,
        nextPageToken: cursor,
	perPage:	pageLimit,
	pageToken: req.query.pageToken,
	total:	total,
      });
    });
  });

  /**
   * POST /api/:modelModule/
   *
   * Create a new object.
   */
  router.post('/', function insert(req, res, next) {
    model.create(req.body, function (err, entity) {
      if (err) { return next(err); }
      res.json(entity);
    });
  });

  /**
   * GET /api/:modelModule/:id
   *
   * Retrieve an object.
   */
  router.get('/:item', function get(req, res, next) {
    model.read(req.params.item, function (err, entity) {
      if (err) { return next(err); }
      res.json(entity);
    });
  });

  /**
   * PUT /api/:modelModule/:id
   *
   * Updates an object.
   */
  router.put('/:item', function update(req, res, next) {
    model.update(req.params.item, req.body, function (err, entity) {
      if (err) { return next(err); }
      res.json(entity);
    });
  });

  /**
   * DELETE /api/:modelModule/:id
   *
   * Deletes an object.
   */
  router.delete('/:item', function _delete(req, res, next) {
    model.delete(req.params.item, function (err) {
      if (err) { return next(err); }
      res.status(200).send('OK');
    });
  });

  /**
   * GET /api/:modelModule/:filterRoute/:field
   *
   * Retrieve a lista of options for filtering (ajax).
   */

/*  router.get(options.routeFilter+'/:field', function listFilter(req, res, next) {
      if (!req.params.field) {res.json({error:'Please append a field name to the request address.'})};
      model.listFilter(req.params.field, pageLimit, req.query.pageToken, function (err, entities, cursor) {
      if (err) { return next(err); }
      res.json({
        items: entities,
        nextPageToken: cursor
      });
    });
  });
*/
  /**
   * Errors on "/api/:modelModule/*" routes.
   */
  router.use(function handleRpcError(err, req, res, next) {
    // Format error and forward to generic error handler for logging and
    // responding to the request
    err.response = {
      message: err.message,
      internalCode: err.code
    };
    next(err);
  });

  return router;
};


text:
/**
 * React component import
 */
import React, { Component } from 'react';

/**
 * Custom component import
 */
import SearchBar from './search_bar';
import ListView from './list_view';
import ItemDetail from './item_detail';

const REFRESH_TOKEN = 'AQCo-tf2_-1SIPcJm06vDO-tPv7FaEWQIHbYwXRSLuicEVf2Eg4UMCxD-YhJOZNoDvigr3HTdB6pqmWR3ozkIrSG3jjdTf9z8DlbjdCFTEugJVcoYNHxnhR4Xb0HwKAsc2I';
const URL = `${window.location.href}spotify-server/refresh_token?refresh_token=${REFRESH_TOKEN}`;

/**
 * App class
 */
class App extends Component {
  /**
   * App constructor
   * @param  {Object} props
   */
  constructor(props) {
    super(props);

    this.searchRequest = this.searchRequest.bind(this);
    this.filterResults = this.filterResults.bind(this);
    this.selectItem = this.selectItem.bind(this);
    this.getAccessToken = this.getAccessToken.bind(this);

    // Initialize state
    this.state = {
      term: '',
      results: [],
      filter: '',
      selectedItem: '',
      auth_code:''
    };
  }

  /**
   * componentDidMount lifecycle callback
   * Asyncronous call is made to spotify server to get auth token
   */
  componentDidMount() {
    this.getAccessToken()
    .then((res) => {
      this.setState({auth_code: 'Bearer ' + res.access_token});
    });
  }

  /**
   * getAccessToken retrieve valid auth token from spotify server
   */
  getAccessToken() {
    return fetch(URL, {method: 'GET'})
    .then((response) => {
      return response.json();
    })
    .catch((err) => {
      console.log(err);
      alert(`Could not get access token from Spotify due to:${err}`);
    });
  }

  /**
   * Initiate search request and update state
   * @param  {String} term [search term]
   */
  searchRequest(term) {
    const URL = `https://api.spotify.com/v1/search?q=${term}&type=track`;
    this.setState({
      results: [],
      selectedItem: ''
    });

    if(term) {
      fetch(URL, {
        method: 'GET',
        headers: new Headers({
          'Authorization': this.state.auth_code
        })
      })
      .then((response) => {
        return response.json();
      })
      .then(async (response) => {
        if (response && response.error) {
          const ACCESS_TOKEN = await this.getAccessToken();
          this.setState({'auth_code': ACCESS_TOKEN.access_token});
        }
        if (response && response.tracks) {
          this.setState({results: response.tracks.items});
        }
      });
    }
  }

  /**
   * filter serch results
   * @param  {String} type  [supported name and Popularity]
   * @param  {String} order [supported asc or desc]
   */
  filterResults(type, order) {
    const sorted = this.state.results.sort((a, b) => {
      order === 'ASC' ? a[type] - b[type] : b[type] - a[type];
    });

    this.setState({results: sorted});
  }

  /**
   * select item from list
   * @param  {Object} item
   */
  selectItem(item) {
    this.setState({selectedItem: item});
  }

  /**
   * render component
   */
  render() {
    if(this.state.auth_code === '') {
      return(

      );
    }

    return (

Reactify

          <SearchBar onSearchInput={this.searchRequest} onFilter={this.filterResults} />
          <ItemDetail selectedItem={this.state.selectedItem} />
          <ListView onSelectItem={this.selectItem} list={this.state.results}/>

    );
  }
}

export default App;


text:
CREATE PROCEDURE [dbo].[Observation_Save]
	@Id BIGINT = 0,
	@EventId UNIQUEIDENTIFIER,
	@Comments VARCHAR(1000),
	@SpeciesCode VARCHAR(20),
	@ObservationTypeId UNIQUEIDENTIFIER
AS
	SET NOCOUNT ON;

	DECLARE @SpeciesId UNIQUEIDENTIFIER;
	SELECT @SpeciesId = SpeciesId FROM dbo.Species WHERE AlphaCode = @SpeciesCode;

	UPDATE dbo.Observation SET EventId = @EventId,
								ObservationTypeId = @ObservationTypeId,
								Comments = @Comments,
								SpeciesId = @SpeciesId
	WHERE ObservationId = @Id;

	IF @@ROWCOUNT = 0
	BEGIN
		INSERT INTO dbo.Observation (EventId, SpeciesId, Comments, ObservationTypeId)
		VALUES (@EventId, @SpeciesId, @Comments, @ObservationTypeId)

		SELECT SCOPE_IDENTITY();
	END;
	ELSE
		SELECT @Id;

RETURN 0


text:
<?php

namespace Google\Cloud\Core\Tests\Unit\Batch;

use Google\Cloud\Core\Batch\BatchDaemonTrait;
use Google\Cloud\Core\Testing\TestHelpers;
use Yoast\PHPUnitPolyfills\TestCases\TestCase;

/**
 * @group core
 * @group batch
 */
class BatchDaemonTraitTest extends TestCase
{
    public function set_up()
    {
        $this->impl = TestHelpers::impl(BatchDaemonTrait::class);
    }

    public function testIsDaemonRunning()
    {
        // Clear the env
        $orig = getenv('IS_BATCH_DAEMON_RUNNING');
        try {
            putenv('IS_BATCH_DAEMON_RUNNING');
            $this->assertFalse($this->impl->call('isDaemonRunning'));
            putenv('IS_BATCH_DAEMON_RUNNING=true');
            $this->assertTrue($this->impl->call('isDaemonRunning'));
        } finally {
            if ($orig === false) {
                putenv('IS_BATCH_DAEMON_RUNNING');
            } else {
                putenv('IS_BATCH_DAEMON_RUNNING=' . $orig);
            }
        }
    }
}


text:
<title>Mesa FAQ</title>

<link rel="stylesheet" type="text/css" href="mesa.css">

Mesa Frequently Asked Questions

Last updated: 21 August 2006

Index

1. High-level Questions and Answers

2. Compilation and Installation Problems

3. Runtime / Rendering Problems

4. Developer Questions

1. High-level Questions and Answers

1.1 What is Mesa?

Mesa is an open-source implementation of the OpenGL specification.
OpenGL is a programming library for writing interactive 3D applications.
See the OpenGL website for more
information.

Mesa 6.x supports the OpenGL 1.5 specification.

1.2 Does Mesa support/use graphics hardware?

Yes.  Specifically, Mesa serves as the OpenGL core for the open-source DRI
drivers for XFree86/X.org.  See the DRI
website for more information.

There have been other hardware drivers for Mesa over the years (such as
the 3Dfx Glide/Voodoo driver, an old S3 driver, etc) but the DRI drivers
are the modern ones.

1.3 What purpose does Mesa serve today?

Hardware-accelerated OpenGL implementations are available for most popular
operating systems today.
Still, Mesa serves at least these purposes:

Mesa is used as the core of the open-source XFree86/X.org DRI
    hardware drivers.

Mesa is quite portable and allows OpenGL to be used on systems
    that have no other OpenGL solution.

Software rendering with Mesa serves as a reference for validating the
    hardware drivers.

A software implementation of OpenGL is useful for experimentation,
    such as testing new rendering techniques.

Mesa can render images with deep color channels: 16-bit integer
    and 32-bit floating point color channels are supported.
    This capability is only now appearing in hardware.

Mesa's internal limits (max lights, clip planes, texture size, etc) can be
    changed for special needs (hardware limits are hard to overcome).

1.4 What's the difference between"Stand-Alone" Mesa and the DRI drivers?

Stand-alone Mesa is the original incarnation of Mesa.
On systems running the X Window System it does all its rendering through
the Xlib API:

The GLX API is supported, but it's really just an emulation of the
     real thing.

The GLX wire protocol is not supported and there's no OpenGL extension
    loaded by the X server.

There is no hardware acceleration.

The OpenGL library, libGL.so, contains everything (the programming API,
    the GLX functions and all the rendering code).

Alternately, Mesa acts as the core for a number of OpenGL hardware drivers
within the DRI (Direct Rendering Infrastructure):

The libGL.so library provides the GL and GLX API functions, a GLX
    protocol encoder, and a device driver loader.

The device driver modules (such as r200_dri.so) contain a built-in
    copy of the core Mesa code.

The X server loads the GLX module.
    The GLX module decodes incoming GLX protocol and dispatches the commands
    to a rendering module.
    For the DRI, this module is basically a software Mesa renderer.

1.5 How do I upgrade my DRI installation to use a new Mesa release?

This wasn't easy in the past.
Now, the DRI drivers are included in the Mesa tree and can be compiled
separately from the X server.
Just follow the Mesa compilation instructions.

1.6 Are there other open-source implementations of OpenGL?

Yes, SGI's
OpenGL Sample Implemenation (SI) is available.
The SI was written during the time that OpenGL was originally designed.
Unfortunately, development of the SI has stagnated.
Mesa is much more up to date with modern features and extensions.

Vincent is
an open-source implementation of OpenGL ES for mobile devices.

miniGL
is a subset of OpenGL for PalmOS devices.

TinyGL is a subset of OpenGL.

SoftGL
is an OpenGL subset for mobile devices.

Chromium
isn't a conventional OpenGL implementation (it's layered upon OpenGL),
but it does export the OpenGL API.  It allows tiled rendering, sort-last
rendering, etc.

ClosedGL is an OpenGL subset library for TI
graphing calculators.

There may be other open OpenGL implementations, but Mesa is the most
popular and feature-complete.

2. Compilation and Installation Problems

2.1 What's the easiest way to install Mesa?

If you're using a Linux-based system, your distro CD most likely already
has Mesa packages (like RPM or DEB) which you can easily install.

2.2 I get undefined symbols such as bgnpolygon, v3f, etc...

You're application is written in IRIS GL, not OpenGL.
IRIS GL was the predecessor to OpenGL and is a different thing (almost)
entirely.
Mesa's not the solution.

2.3 Where is the GLUT library?

GLUT (OpenGL Utility Toolkit) is in the separate MesaGLUT-x.y.z.tar.gz file.
If you don't already have GLUT installed, you should grab the MesaGLUT
package and compile it with the rest of Mesa.

2.4 What's the proper place for the libraries and headers?

On Linux-based systems you'll want to follow the
Linux ABI standard.
Basically you'll want the following:

/usr/include/GL/gl.h - the main OpenGL header

/usr/include/GL/glu.h - the OpenGL GLU (utility) header

/usr/include/GL/glx.h - the OpenGL GLX header

/usr/include/GL/glext.h - the OpenGL extensions header

/usr/include/GL/glxext.h - the OpenGL GLX extensions header

/usr/include/GL/osmesa.h - the Mesa off-screen rendering header

/usr/lib/libGL.so - a symlink to libGL.so.1

/usr/lib/libGL.so.1 - a symlink to libGL.so.1.xyz

/usr/lib/libGL.so.xyz - the actual OpenGL/Mesa library.  xyz denotes the
Mesa version number.

/usr/lib/libGLU.so - a symlink to libGLU.so.1

/usr/lib/libGLU.so.1 - a symlink to libGLU.so.1.3.xyz

/usr/lib/libGLU.so.xyz - the OpenGL Utility library.  xyz denotes the Mesa
version number.

After installing XFree86/X.org and the DRI drivers, some of these files
may be symlinks into the /usr/X11R6/ tree.

The old-style Makefile system doesn't install the Mesa libraries; it's
up to you to copy them (and the headers) to the right place.

The GLUT header and library should go in the same directories.

3. Runtime / Rendering Problems

3.1 Rendering is slow / why isn't my graphics hardware being used?

Stand-alone Mesa (downloaded as MesaLib-x.y.z.tar.gz) doesn't have any
support for hardware acceleration (with the exception of the 3DFX Voodoo
driver).

What you really want is a DRI or NVIDIA (or another vendor's OpenGL) driver
for your particular hardware.

You can run the glxinfo program to learn about your OpenGL
library.
Look for the GL_VENDOR and GL_RENDERER values.
That will identify who's OpenGL library you're using and what sort of
hardware it has detected.

If your DRI-based driver isn't working, go to the
DRI website for trouble-shooting information.

3.2 I'm seeing errors in depth (Z) buffering.  Why?

Make sure the ratio of the far to near clipping planes isn't too great.
Look
 here for details.

Mesa uses a 16-bit depth buffer by default which is smaller and faster
to clear than a 32-bit buffer but not as accurate.
If you need a deeper you can modify the parameters to
 glXChooseVisual in your code.

3.3 Why Isn't depth buffering working at all?

Be sure you're requesting a depth buffered-visual.  If you set the MESA_DEBUG
environment variable it will warn you about trying to enable depth testing
when you don't have a depth buffer.

Specifically, make sure glutInitDisplayMode is being called
with GLUT_DEPTH or glXChooseVisual is being
called with a non-zero value for GLX_DEPTH_SIZE.

This discussion applies to stencil buffers, accumulation buffers and
alpha channels too.

3.4 Why does glGetString() always return NULL?

Be sure you have an active/current OpenGL rendering context before
calling glGetString.

3.5 GL_POINTS and GL_LINES don't touch the right pixels

If you're trying to draw a filled region by using GL_POINTS or GL_LINES
and seeing holes or gaps it's because of a float-to-int rounding problem.
But this is not a bug.
See Appendix H of the OpenGL Programming Guide - "OpenGL Correctness Tips".
Basically, applying a translation of (0.375, 0.375, 0.0) to your coordinates
will fix the problem.

4. Developer Questions

4.1 How can I contribute?

First, join the Mesa3d-dev
mailing list.
That's where Mesa development is discussed.

The
OpenGL Specification is the bible for OpenGL implemention work.
You should read it.

Most of the Mesa development work involves implementing new OpenGL
extensions, writing hardware drivers (for the DRI), and code optimization.

4.2 How do I write a new device driver?

Unfortunately, writing a device driver isn't easy.
It requires detailed understanding of OpenGL, the Mesa code, and your
target hardware/operating system.
3D graphics are not simple.

The best way to get started is to use an existing driver as your starting
point.
For a software driver, the X11 and OSMesa drivers are good examples.
For a hardware driver, the Radeon and R200 DRI drivers are good examples.

The DRI website has more information about writing hardware drivers.
The process isn't well document because the Mesa driver interface changes
over time, and we seldome have spare time for writing documentation.
That being said, many people have managed to figure out the process.

Joining the appropriate mailing lists and asking questions (and searching
the archives) is a good way to get information.

4.3 Why isn't GL_EXT_texture_compression_s3tc implemented in Mesa?

The specification for the extension
indicates that there are intellectual property (IP) and/or patent issues
to be dealt with.

We've been unsucessful in getting a response from S3 (or whoever owns
the IP nowadays) to indicate whether or not an open source project can
implement the extension (specifically the compression/decompression
algorithms).

In the mean time, a 3rd party plug-in library is available.


text:
package logrus

import (
	"time"

	log "github.com/sirupsen/logrus"
)

const DefaultTimestampFormat = time.RFC3339

// This is to not silently overwrite `time`, `msg` and `level` fields when
// dumping it. If this code wasn't there doing:
//
//  logrus.WithField("level", 1).Info("hello")
//
// Would just silently drop the user provided level. Instead with this code
// it'll logged as:
//
//  {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."}
//
// It's not exported because it's still using Data in an opinionated way. It's to
// avoid code duplication between the two default formatters.
//
// More information at https://github.com/akutz/logrus/blob/master/formatter.go
func prefixFieldClashes(data log.Fields) {
	_, ok := data["time"]
	if ok {
		data["fields.time"] = data["time"]
	}

	_, ok = data["msg"]
	if ok {
		data["fields.msg"] = data["msg"]
	}

	_, ok = data["level"]
	if ok {
		data["fields.level"] = data["level"]
	}
}


text:
Provides commands to quickly view the current file on [Bitbucket](https://bitbucket.org) or [Bitbucket Server](https://www.atlassian.com/software/bitbucket/server) (formerly Stash).

## Usage

When editing a file in Atom, use the command palette or keyboard shortcuts to:

- Open the file on bitbucket.org `alt-b, o`
- Open the blame view for the file on bitbucket.org `alt-b, b`
- Open the history view for the file on bitbucket.org `alt-b, h`
- Open the issues view for the repository the file belongs to on github.com `alt-g, i`
- Open the compare page for the current branch on bitbucket.org `alt-b, r`
- Copy the bitbucket.org URL for the currently selected lines `alt-b, c`

![Command Palette](https://cloud.githubusercontent.com/assets/472350/7668596/86267acc-fc06-11e4-92e4-8737a632a021.png)

---

Inspired by the [Open on Github package][open-on-github] for Atom.

[open-on-github]: https://github.com/atom/open-on-github


text:
#include <list>
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread/mutex.hpp>

#include <boost/config/abi_prefix.hpp>

#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4251)
#endif

namespace boost
{
    class thread_group
    {
    private:
        thread_group(thread_group const&);
        thread_group& operator=(thread_group const&);
    public:
        thread_group() {}
        ~thread_group()
        {
            for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
                it!=end;
                ++it)
            {
                delete *it;
            }
        }

        template<typename F>
        thread* create_thread(F threadfunc)
        {
            boost::lock_guard<shared_mutex> guard(m);
            std::auto_ptr<thread> new_thread(new thread(threadfunc));
            threads.push_back(new_thread.get());
            return new_thread.release();
        }

        void add_thread(thread* thrd)
        {
            if(thrd)
            {
                boost::lock_guard<shared_mutex> guard(m);
                threads.push_back(thrd);
            }
        }

        void remove_thread(thread* thrd)
        {
            boost::lock_guard<shared_mutex> guard(m);
            std::list<thread*>::iterator const it=std::find(threads.begin(),threads.end(),thrd);
            if(it!=threads.end())
            {
                threads.erase(it);
            }
        }

        void join_all()
        {
            boost::shared_lock<shared_mutex> guard(m);

            for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
                it!=end;
                ++it)
            {
                (*it)->join();
            }
        }

        void interrupt_all()
        {
            boost::shared_lock<shared_mutex> guard(m);

            for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
                it!=end;
                ++it)
            {
                (*it)->interrupt();
            }
        }

        size_t size() const
        {
            boost::shared_lock<shared_mutex> guard(m);
            return threads.size();
        }

    private:
        std::list<thread*> threads;
        mutable shared_mutex m;
    };
}

#ifdef BOOST_MSVC
#pragma warning(pop)
#endif

#include <boost/config/abi_suffix.hpp>

#endif


text:
// <copyright file="BasicUiRestrictions.cs" company="Nikolay Kostov (Nikolay.IT)">
// Copyright (c) Nikolay Kostov (Nikolay.IT). All Rights Reserved.
// Licensed under the Apache License. See LICENSE in the project root for license information.
// </copyright>

namespace RestrictedProcess.JobObjects
{
    using System.Runtime.InteropServices;

    /// <summary>
    /// Contains basic user-interface restrictions for a job object.
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    internal struct BasicUiRestrictions
    {
        /// <summary>
        /// Gets or sets the restriction class for the user interface.
        /// </summary>
        public uint UIRestrictionsClass { get; set; }
    }
}


text:
function Cleanup-AzureRmPublicIPAddress
{
<#
.Synopsis
   Cleanup-AzureRmPublicIPAddress removes Public IP Addresses that are not linked
   to an Azure VirtualMachine
.DESCRIPTION
   Use the Cleanup-AzureRmPublicIPAddress to remove Azure Public IP Addresses that
   are not linked to an existing Azure VirtualMachine based on the IPConfiguration data
   being empty.
.PARAMETER ResourceGrup
   Specifies the name of the resource group from which Public IP Addresses are
   to be retrieved.
.PARAMETER ListOnly
  Only lists Azure Public IP Addresses that are not linked to an existing Azure Virtual Machine

.EXAMPLE
   Cleanup-AzureRmPublicIPAddress -ResourceGroup RG_2
.EXAMPLE
   Cleanup-AzureRmPublicIPAddress -ResourceGroup RG_2 -ListOnly

   Lists all Public IP Addresses that have no association to a virtual machine.

    Name    ResourceGuid
    ----    ------------
    vm01-ip b5c0f73b-abda-4a24-b3bd-2722b08aabe0
    VM2-ip  f03360f2-887e-44fe-a5ad-396195cd8efc
    VM3-ip  5db8d1fa-f551-4794-a9c0-27cd005b4742
.NOTES
    Alex Verboon, version 1.0, 01.10.2016
#>

   [CmdletBinding(SupportsShouldProcess=$true,
   ConfirmImpact="High")]
    Param
    (
        # Specifies the name of the resource group from which Public IP Addresses are to be retrieved.
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=0)]
        [string]$ResourceGroup,
        # Only lists Azure Network Interfaces that are not linked to an existing Azure Virtual Machine
        [switch]$ListOnly
    )
    Begin
    {
        If (AzureRmResourceGroup -Name $ResourceGroup -ErrorAction SilentlyContinue )
        {
            $az_publicipaddress = Get-AzureRmPublicIpAddress -ResourceGroupName $ResourceGroup
            $RemAzPublicIP = $az_publicipaddress |  Where-Object {$_.IpConfiguration -eq $null}
        }
        Else
        {
            Write-Error "Provided resource group does not exist: $ResourceGroup"
            Throw
        }
    }
    Process
    {
        $removed = @()
        If ($PSBoundParameters.ContainsKey("ListOnly"))
        {
            $RemAzPublicIP | Select-Object Name,ResourceGuid
        }
        Else
        {
            ForEach($pi in $RemAzPublicIP)
            {
                if ($pscmdlet.ShouldProcess("Deleting NetworkInterface $($pi.Name)"))
                {
                   Write-Output "Removing Public IP Address without Virtual Machine association: $($pi.Name)"
                   Remove-AzureRmPublicIpAddress -Name "$($pi.name)" -ResourceGroupName $ResourceGroup
                   $object = New-Object -TypeName PSObject
                   $object | Add-Member -MemberType NoteProperty -Name Name -Value $($pi.Name)
                   $object | Add-Member -MemberType NoteProperty -Name ResourceGuid -Value $($pi.ResourceGuid)
                   $removed += $object
                }
            }
        }
    }
    End
    {
        # List the removed objects
        $removed
    }
}


text:
<?xml version="1.0"?>
<!-- Smack configuration file. -->
<smack>
    <!-- Classes that will be loaded when Smack starts -->
    <startupClasses>
        <className>org.jivesoftware.smack.initializer.VmArgInitializer</className>
        <className>org.jivesoftware.smack.ReconnectionManager</className>
    </startupClasses>

    <optionalStartupClasses>
        <className>org.jivesoftware.smack.util.dns.javax.JavaxResolver</className>
        <className>org.jivesoftware.smack.util.dns.minidns.MiniDnsResolver</className>
        <className>org.jivesoftware.smack.util.dns.dnsjava.DNSJavaResolver</className>
        <className>org.jivesoftware.smack.extensions.ExtensionsInitializer</className>
        <className>org.jivesoftware.smack.experimental.ExperimentalInitializer</className>
        <className>org.jivesoftware.smack.legacy.LegacyInitializer</className>
        <className>org.jivesoftware.smack.tcp.TCPInitializer</className>
        <className>org.jivesoftware.smack.sasl.javax.SASLJavaXSmackInitializer</className>
        <className>org.jivesoftware.smack.sasl.provided.SASLProvidedSmackInitializer</className>
        <className>org.jivesoftware.smack.android.AndroidSmackInitializer</className>
        <className>org.jivesoftware.smack.java7.Java7SmackInitializer</className>
        <className>org.jivesoftware.smack.im.SmackImInitializer</className>
    </optionalStartupClasses>
</smack>