text:
using J2N.Runtime.CompilerServices;
using J2N.Threading.Atomic;
using Lucene.Net.Diagnostics;
using Lucene.Net.Support.Threading;
using System;
using System.Collections.Generic;
using System.Threading;
using JCG = J2N.Collections.Generic;

namespace Lucene.Net.Index
{

    using InfoStream = Lucene.Net.Util.InfoStream;
    using ThreadState = Lucene.Net.Index.DocumentsWriterPerThreadPool.ThreadState;

    /// <summary>
    /// This class controls <see cref="DocumentsWriterPerThread"/> flushing during
    /// indexing. It tracks the memory consumption per
    /// <see cref="DocumentsWriterPerThread"/> and uses a configured <see cref="flushPolicy"/> to
    /// decide if a <see cref="DocumentsWriterPerThread"/> must flush.
    /// <para/>
    /// In addition to the <see cref="flushPolicy"/> the flush control might set certain
    /// <see cref="DocumentsWriterPerThread"/> as flush pending iff a
    /// <see cref="DocumentsWriterPerThread"/> exceeds the
    /// <see cref="IndexWriterConfig.RAMPerThreadHardLimitMB"/> to prevent address
    /// space exhaustion.
    /// </summary>
    internal sealed class DocumentsWriterFlushControl
    {
        private readonly long hardMaxBytesPerDWPT;
        private long activeBytes = 0;
        private long flushBytes = 0;
        private volatile int numPending = 0;
        private int numDocsSinceStalled = 0; // only with assert
        internal readonly AtomicBoolean flushDeletes = new AtomicBoolean(false);
        private bool fullFlush = false;
        private readonly Queue<DocumentsWriterPerThread> flushQueue = new Queue<DocumentsWriterPerThread>();

        // only for safety reasons if a DWPT is close to the RAM limit
        private readonly LinkedList<BlockedFlush> blockedFlushes = new LinkedList<BlockedFlush>();

        private readonly IDictionary<DocumentsWriterPerThread, long> flushingWriters = new JCG.Dictionary<DocumentsWriterPerThread, long>(IdentityEqualityComparer<DocumentsWriterPerThread>.Default);

        internal double maxConfiguredRamBuffer = 0;
        internal long peakActiveBytes = 0; // only with assert
        internal long peakFlushBytes = 0; // only with assert
        internal long peakNetBytes = 0; // only with assert
        internal long peakDelta = 0; // only with assert
        internal readonly DocumentsWriterStallControl stallControl;
        private readonly DocumentsWriterPerThreadPool perThreadPool;
        private readonly FlushPolicy flushPolicy;
        private bool closed = false;
        private readonly DocumentsWriter documentsWriter;
        private readonly LiveIndexWriterConfig config;
        private readonly BufferedUpdatesStream bufferedUpdatesStream;
        private readonly InfoStream infoStream;

        internal DocumentsWriterFlushControl(DocumentsWriter documentsWriter, LiveIndexWriterConfig config, BufferedUpdatesStream bufferedUpdatesStream)
        {
            this.infoStream = config.InfoStream;
            this.stallControl = new DocumentsWriterStallControl();
            this.perThreadPool = documentsWriter.perThreadPool;
            this.flushPolicy = documentsWriter.flushPolicy;
            this.config = config;
            this.hardMaxBytesPerDWPT = config.RAMPerThreadHardLimitMB * 1024 * 1024;
            this.documentsWriter = documentsWriter;
            this.bufferedUpdatesStream = bufferedUpdatesStream;
        }

        public long ActiveBytes
        {
            get
            {
                UninterruptableMonitor.Enter(this);
                try
                {
                    return activeBytes;
                }
                finally
                {
                    UninterruptableMonitor.Exit(this);
                }
            }
        }

        public long FlushBytes
        {
            get
            {
                UninterruptableMonitor.Enter(this);
                try
                {
                    return flushBytes;
                }
                finally
                {
                    UninterruptableMonitor.Exit(this);
                }
            }
        }

        public long NetBytes
        {
            get
            {
                UninterruptableMonitor.Enter(this);
                try
                {
                    return flushBytes + activeBytes;
                }
                finally
                {
                    UninterruptableMonitor.Exit(this);
                }
            }
        }

        private long StallLimitBytes
        {
            get
            {
                double maxRamMB = config.RAMBufferSizeMB;
                return maxRamMB != IndexWriterConfig.DISABLE_AUTO_FLUSH ? (long)(2 * (maxRamMB * 1024 * 1024)) : long.MaxValue;
            }
        }

        private bool AssertMemory()
        {
            double maxRamMB = config.RAMBufferSizeMB;
            if (maxRamMB != IndexWriterConfig.DISABLE_AUTO_FLUSH)
            {
                // for this assert we must be tolerant to ram buffer changes!
                maxConfiguredRamBuffer = Math.Max(maxRamMB, maxConfiguredRamBuffer);
                long ram = flushBytes + activeBytes;
                long ramBufferBytes = (long)(maxConfiguredRamBuffer * 1024 * 1024);
                // take peakDelta into account - worst case is that all flushing, pending and blocked DWPT had maxMem and the last doc had the peakDelta

                // 2 * ramBufferBytes -> before we stall we need to cross the 2xRAM Buffer border this is still a valid limit
                // (numPending + numFlushingDWPT() + numBlockedFlushes()) * peakDelta) -> those are the total number of DWPT that are not active but not yet fully fluhsed
                // all of them could theoretically be taken out of the loop once they crossed the RAM buffer and the last document was the peak delta
                // (numDocsSinceStalled * peakDelta) -> at any given time there could be n threads in flight that crossed the stall control before we reached the limit and each of them could hold a peak document
                long expected = (2 * (ramBufferBytes)) + ((numPending + NumFlushingDWPT + NumBlockedFlushes) * peakDelta) + (numDocsSinceStalled * peakDelta);
                // the expected ram consumption is an upper bound at this point and not really the expected consumption
                if (peakDelta < (ramBufferBytes >> 1))
                {
                    /*
                     * if we are indexing with very low maxRamBuffer like 0.1MB memory can
                     * easily overflow if we check out some DWPT based on docCount and have
                     * several DWPT in flight indexing large documents (compared to the ram
                     * buffer). this means that those DWPT and their threads will not hit
                     * the stall control before asserting the memory which would in turn
                     * fail. To prevent this we only assert if the the largest document seen
                     * is smaller than the 1/2 of the maxRamBufferMB
                     */
                    if (Debugging.AssertsEnabled) Debugging.Assert(ram <= expected,
                        "actual mem: {0} byte, expected mem: {1}"
                        + " byte, flush mem: {2}, active mem: {3}"
                        + ", pending DWPT: {4}, flushing DWPT: {5}"
                        + ", blocked DWPT: {6}, peakDelta mem: {7} byte", ram, expected, flushBytes, activeBytes, numPending, NumFlushingDWPT, NumBlockedFlushes, peakDelta);
                }
            }
            return true;
        }

        private void CommitPerThreadBytes(ThreadState perThread)
        {
            long delta = perThread.dwpt.BytesUsed - perThread.bytesUsed;
            perThread.bytesUsed += delta;
            /*
             * We need to differentiate here if we are pending since setFlushPending
             * moves the perThread memory to the flushBytes and we could be set to
             * pending during a delete
             */
            if (perThread.flushPending)
            {
                flushBytes += delta;
            }
            else
            {
                activeBytes += delta;
            }
            if (Debugging.AssertsEnabled) Debugging.Assert(UpdatePeaks(delta));
        }

        // only for asserts
        private bool UpdatePeaks(long delta)
        {
            peakActiveBytes = Math.Max(peakActiveBytes, activeBytes);
            peakFlushBytes = Math.Max(peakFlushBytes, flushBytes);
            peakNetBytes = Math.Max(peakNetBytes, NetBytes);
            peakDelta = Math.Max(peakDelta, delta);

            return true;
        }

        internal DocumentsWriterPerThread DoAfterDocument(ThreadState perThread, bool isUpdate)
        {
            UninterruptableMonitor.Enter(this);
            try
            {
                try
                {
                    CommitPerThreadBytes(perThread);
                    if (!perThread.flushPending)
                    {
                        if (isUpdate)
                        {
                            flushPolicy.OnUpdate(this, perThread);
                        }
                        else
                        {
                            flushPolicy.OnInsert(this, perThread);
                        }
                        if (!perThread.flushPending && perThread.bytesUsed > hardMaxBytesPerDWPT)
                        {
                            // Safety check to prevent a single DWPT exceeding its RAM limit. this
                            // is super important since we can not address more than 2048 MB per DWPT
                            SetFlushPending(perThread);
                        }
                    }
                    DocumentsWriterPerThread flushingDWPT;
                    if (fullFlush)
                    {
                        if (perThread.flushPending)
                        {
                            CheckoutAndBlock(perThread);
                            flushingDWPT = NextPendingFlush();
                        }
                        else
                        {
                            flushingDWPT = null;
                        }
                    }
                    else
                    {
                        flushingDWPT = TryCheckoutForFlush(perThread);
                    }
                    return flushingDWPT;
                }
                finally
                {
                    bool stalled = UpdateStallState();
                    if (Debugging.AssertsEnabled) Debugging.Assert(AssertNumDocsSinceStalled(stalled) && AssertMemory());
                }
            }
            finally
            {
                UninterruptableMonitor.Exit(this);
            }
        }

        private bool AssertNumDocsSinceStalled(bool stalled)
        {
            /*
             *  updates the number of documents "finished" while we are in a stalled state.
             *  this is important for asserting memory upper bounds since it corresponds
             *  to the number of threads that are in-flight and crossed the stall control
             *  check before we actually stalled.
             *  see #assertMemory()
             */
            if (stalled)
            {
                numDocsSinceStalled++;
            }
            else
            {
                numDocsSinceStalled = 0;
            }
            return true;
        }

        internal void DoAfterFlush(DocumentsWriterPerThread dwpt)
        {
            UninterruptableMonitor.Enter(this);
            try
            {
                if (Debugging.AssertsEnabled) Debugging.Assert(flushingWriters.ContainsKey(dwpt));
                try
                {
                    long bytes = flushingWriters[dwpt];
                    flushingWriters.Remove(dwpt);
                    flushBytes -= bytes;
                    //perThreadPool.Recycle(dwpt); // LUCENENET: This is a no-op method in Lucene and it cannot be overridden
                    if (Debugging.AssertsEnabled) Debugging.Assert(AssertMemory());
                }
                finally
                {
                    try
                    {
                        UpdateStallState();
                    }
                    finally
                    {
                        UninterruptableMonitor.PulseAll(this);
                    }
                }
            }
            finally
            {
                UninterruptableMonitor.Exit(this);
            }
        }

        private bool UpdateStallState()
        {
            if (Debugging.AssertsEnabled) Debugging.Assert(UninterruptableMonitor.IsEntered(this));
            long limit = StallLimitBytes;
            /*
             * we block indexing threads if net byte grows due to slow flushes
             * yet, for small ram buffers and large documents we can easily
             * reach the limit without any ongoing flushes. we need to ensure
             * that we don't stall/block if an ongoing or pending flush can
             * not free up enough memory to release the stall lock.
             */
            bool stall = ((activeBytes + flushBytes) > limit) && (activeBytes < limit) && !closed;
            stallControl.UpdateStalled(stall);
            return stall;
        }

        public void WaitForFlush()
        {
            UninterruptableMonitor.Enter(this);
            try
            {
                while (flushingWriters.Count != 0)
                {
                    try
                    {
                        UninterruptableMonitor.Wait(this);
                    }
                    catch (Exception ie) when (ie.IsInterruptedException())
                    {
                        throw new Util.ThreadInterruptedException(ie);
                    }
                }
            }
            finally
            {
                UninterruptableMonitor.Exit(this);
            }
        }

        /// <summary>
        /// Sets flush pending state on the given <see cref="ThreadState"/>. The
        /// <see cref="ThreadState"/> must have indexed at least on <see cref="Documents.Document"/> and must not be
        /// already pending.
        /// </summary>
        public void SetFlushPending(ThreadState perThread)
        {
            UninterruptableMonitor.Enter(this);
            try
            {
                if (Debugging.AssertsEnabled) Debugging.Assert(!perThread.flushPending);
                if (perThread.dwpt.NumDocsInRAM > 0)
                {
                    perThread.flushPending = true; // write access synced
                    long bytes = perThread.bytesUsed;
                    flushBytes += bytes;
                    activeBytes -= bytes;
                    numPending++; // write access synced
                    if (Debugging.AssertsEnabled) Debugging.Assert(AssertMemory());
                } // don't assert on numDocs since we could hit an abort excp. while selecting that dwpt for flushing
            }
            finally
            {
                UninterruptableMonitor.Exit(this);
            }
        }

        internal void DoOnAbort(ThreadState state)
        {
            UninterruptableMonitor.Enter(this);
            try
            {
                try
                {
                    if (state.flushPending)
                    {
                        flushBytes -= state.bytesUsed;
                    }
                    else
                    {
                        activeBytes -= state.bytesUsed;
                    }
                    if (Debugging.AssertsEnabled) Debugging.Assert(AssertMemory());
                    // Take it out of the loop this DWPT is stale
                    DocumentsWriterPerThreadPool.Reset(state, closed); // LUCENENET specific - made static per CA1822
                }
                finally
                {
                    UpdateStallState();
                }
            }
            finally
            {
                UninterruptableMonitor.Exit(this);
            }
        }

        internal DocumentsWriterPerThread TryCheckoutForFlush(ThreadState perThread)
        {
            UninterruptableMonitor.Enter(this);
            try
            {
                if (Debugging.AssertsEnabled) Debugging.Assert(perThread.IsHeldByCurrentThread); // LUCENENET specific: Since .NET Core doesn't use unfair locking, we need to ensure the current thread has a lock before calling InternalTryCheckoutForFlush.
                return perThread.flushPending ? InternalTryCheckOutForFlush(perThread) : null;
            }
            finally
            {
                UninterruptableMonitor.Exit(this);
            }
        }

        private void CheckoutAndBlock(ThreadState perThread)
        {
            perThread.@Lock();
            try
            {
                if (Debugging.AssertsEnabled)
                {
                    Debugging.Assert(perThread.flushPending, "can not block non-pending threadstate");
                    Debugging.Assert(fullFlush, "can not block if fullFlush == false");
                }
                DocumentsWriterPerThread dwpt;
                long bytes = perThread.bytesUsed;
                dwpt = DocumentsWriterPerThreadPool.Reset(perThread, closed); // LUCENENET specific - made method static per CA1822
                numPending--;
                blockedFlushes.AddLast(new BlockedFlush(dwpt, bytes));
            }
            finally
            {
                perThread.Unlock();
            }
        }

        private DocumentsWriterPerThread InternalTryCheckOutForFlush(ThreadState perThread)
        {
            if (Debugging.AssertsEnabled)
            {
                // LUCENENET specific - Since we need to mimic the unfair behavior of ReentrantLock, we need to ensure that all threads that enter here hold the lock.
                Debugging.Assert(perThread.IsHeldByCurrentThread);
                Debugging.Assert(UninterruptableMonitor.IsEntered(this));
                Debugging.Assert(perThread.flushPending);
            }
            try
            {
                // LUCENENET specific - We removed the call to perThread.TryLock() and the try-finally below as they are no longer needed.

                // We are pending so all memory is already moved to flushBytes
                if (perThread.IsInitialized)
                {
                    if (Debugging.AssertsEnabled) Debugging.Assert(perThread.IsHeldByCurrentThread);
                    DocumentsWriterPerThread dwpt;
                    long bytes = perThread.bytesUsed; // do that before
                    // replace!
                    dwpt = DocumentsWriterPerThreadPool.Reset(perThread, closed); // LUCENENET specific - made method static per CA1822
                    if (Debugging.AssertsEnabled) Debugging.Assert(!flushingWriters.ContainsKey(dwpt), "DWPT is already flushing");
                    // Record the flushing DWPT to reduce flushBytes in doAfterFlush
                    flushingWriters[dwpt] = bytes;
                    numPending--; // write access synced
                    return dwpt;
                }
                return null;
            }
            finally
            {
                UpdateStallState();
            }
        }

        public override string ToString()
        {
            return "DocumentsWriterFlushControl [activeBytes=" + activeBytes + ", flushBytes=" + flushBytes + "]";
        }

        internal DocumentsWriterPerThread NextPendingFlush()
        {
            int numPending;
            bool fullFlush;
            UninterruptableMonitor.Enter(this);
            try
            {
                DocumentsWriterPerThread poll;
                if (flushQueue.Count > 0 && (poll = flushQueue.Dequeue()) != null)
                {
                    UpdateStallState();
                    return poll;
                }
                fullFlush = this.fullFlush;
                numPending = this.numPending;
            }
            finally
            {
                UninterruptableMonitor.Exit(this);
            }
            if (numPending > 0 && !fullFlush) // don't check if we are doing a full flush
            {
                int limit = perThreadPool.NumThreadStatesActive;
                for (int i = 0; i < limit && numPending > 0; i++)
                {
                    ThreadState next = perThreadPool.GetThreadState(i);
                    if (next.flushPending && next.TryLock()) // LUCENENET specific: Since .NET Core 2+ uses fair locking, we need to ensure we have a lock before calling InternalTryCheckoutForFlush. See #
                    {
                        try
                        {
                            DocumentsWriterPerThread dwpt = TryCheckoutForFlush(next);
                            if (dwpt != null)
                            {
                                return dwpt;
                            }
                        }
                        finally
                        {
                            next.Unlock();
                        }
                    }
                }
            }
            return null;
        }

        internal void SetClosed()
        {
            UninterruptableMonitor.Enter(this);
            try
            {
                // set by DW to signal that we should not release new DWPT after close
                if (!closed)
                {
                    this.closed = true;
                    perThreadPool.DeactivateUnreleasedStates();
                }
            }
            finally
            {
                UninterruptableMonitor.Exit(this);
            }
        }

        /// <summary>
        /// Returns an iterator that provides access to all currently active <see cref="ThreadState"/>s
        /// </summary>
        public IEnumerator<ThreadState> AllActiveThreadStates()
        {
            return GetPerThreadsIterator(perThreadPool.NumThreadStatesActive);
        }

        private IEnumerator<ThreadState> GetPerThreadsIterator(int upto)
        {
            return new EnumeratorAnonymousClass(this, upto);
        }

        private sealed class EnumeratorAnonymousClass : IEnumerator<ThreadState>
        {
            private readonly DocumentsWriterFlushControl outerInstance;
            private ThreadState current;
            private readonly int upto;
            private int i;

            public EnumeratorAnonymousClass(DocumentsWriterFlushControl outerInstance, int upto)
            {
                this.outerInstance = outerInstance;
                this.upto = upto;
                i = 0;
            }

            public ThreadState Current => current;

            public void Dispose()
            {
                // LUCENENET: Intentionally blank
            }

            object System.Collections.IEnumerator.Current => Current;

            public bool MoveNext()
            {
                if (i < upto)
                {
                    current = outerInstance.perThreadPool.GetThreadState(i++);
                    return true;
                }

                return false;
            }

            public void Reset()
            {
                throw UnsupportedOperationException.Create();
            }
        }

        internal void DoOnDelete()
        {
            UninterruptableMonitor.Enter(this);
            try
            {
                // pass null this is a global delete no update
                flushPolicy.OnDelete(this, null);
            }
            finally
            {
                UninterruptableMonitor.Exit(this);
            }
        }

        /// <summary>
        /// Returns the number of delete terms in the global pool
        /// </summary>
        public int NumGlobalTermDeletes => documentsWriter.deleteQueue.NumGlobalTermDeletes + bufferedUpdatesStream.NumTerms;

        public long DeleteBytesUsed => documentsWriter.deleteQueue.BytesUsed + bufferedUpdatesStream.BytesUsed;

        internal int NumFlushingDWPT
        {
            get
            {
                UninterruptableMonitor.Enter(this);
                try
                {
                    return flushingWriters.Count;
                }
                finally
                {
                    UninterruptableMonitor.Exit(this);
                }
            }
        }

        public bool GetAndResetApplyAllDeletes()
        {
            return flushDeletes.GetAndSet(false);
        }

        public void SetApplyAllDeletes()
        {
            flushDeletes.Value = true;
        }

        internal int NumActiveDWPT => this.perThreadPool.NumThreadStatesActive;

        internal ThreadState ObtainAndLock()
        {
            ThreadState perThread = perThreadPool.GetAndLock(/* Thread.CurrentThread, documentsWriter // LUCENENET: Not used */);
            bool success = false;
            try
            {
                if (perThread.IsInitialized && perThread.dwpt.deleteQueue != documentsWriter.deleteQueue)
                {
                    // There is a flush-all in process and this DWPT is
                    // now stale -- enroll it for flush and try for
                    // another DWPT:
                    AddFlushableState(perThread);
                }
                success = true;
                // simply return the ThreadState even in a flush all case sine we already hold the lock
                return perThread;
            }
            finally
            {
                if (!success) // make sure we unlock if this fails
                {
                    perThreadPool.Release(perThread);
                }
            }
        }

        internal void MarkForFullFlush()
        {
            DocumentsWriterDeleteQueue flushingQueue;
            UninterruptableMonitor.Enter(this);
            try
            {
                if (Debugging.AssertsEnabled)
                {
                    Debugging.Assert(!fullFlush, "called DWFC#markForFullFlush() while full flush is still running");
                    Debugging.Assert(fullFlushBuffer.Count == 0,"full flush buffer should be empty: {0}", fullFlushBuffer);
                }
                fullFlush = true;
                flushingQueue = documentsWriter.deleteQueue;
                // Set a new delete queue - all subsequent DWPT will use this queue until
                // we do another full flush
                DocumentsWriterDeleteQueue newQueue = new DocumentsWriterDeleteQueue(flushingQueue.generation + 1);
                documentsWriter.deleteQueue = newQueue;
            }
            finally
            {
                UninterruptableMonitor.Exit(this);
            }
            int limit = perThreadPool.NumThreadStatesActive;
            for (int i = 0; i < limit; i++)
            {
                ThreadState next = perThreadPool.GetThreadState(i);
                next.@Lock();
                try
                {
                    if (!next.IsInitialized)
                    {
                        if (closed && next.IsActive)
                        {
                            DocumentsWriterPerThreadPool.DeactivateThreadState(next); // LUCENENET specific - made method static per CA1822
                        }
                        continue;
                    }
                    if (Debugging.AssertsEnabled) Debugging.Assert(next.dwpt.deleteQueue == flushingQueue
                        || next.dwpt.deleteQueue == documentsWriter.deleteQueue,
                        " flushingQueue: {0} currentqueue: {1} perThread queue: {2} numDocsInRam: {3}",
                        flushingQueue, documentsWriter.deleteQueue, next.dwpt.deleteQueue, next.dwpt.NumDocsInRAM);
                    if (next.dwpt.deleteQueue != flushingQueue)
                    {
                        // this one is already a new DWPT
                        continue;
                    }
                    AddFlushableState(next);
                }
                finally
                {
                    next.Unlock();
                }
            }
            UninterruptableMonitor.Enter(this);
            try
            {
                /* make sure we move all DWPT that are where concurrently marked as
                 * pending and moved to blocked are moved over to the flushQueue. There is
                 * a chance that this happens since we marking DWPT for full flush without
                 * blocking indexing.*/
                PruneBlockedQueue(flushingQueue);
                if (Debugging.AssertsEnabled) Debugging.Assert(AssertBlockedFlushes(documentsWriter.deleteQueue));
                //FlushQueue.AddAll(FullFlushBuffer);
                foreach (var dwpt in fullFlushBuffer)
                {
                    flushQueue.Enqueue(dwpt);
                }
                fullFlushBuffer.Clear();
                UpdateStallState();
            }
            finally
            {
                UninterruptableMonitor.Exit(this);
            }
            if (Debugging.AssertsEnabled) Debugging.Assert(AssertActiveDeleteQueue(documentsWriter.deleteQueue));
        }

        private bool AssertActiveDeleteQueue(DocumentsWriterDeleteQueue queue)
        {
            int limit = perThreadPool.NumThreadStatesActive;
            for (int i = 0; i < limit; i++)
            {
                ThreadState next = perThreadPool.GetThreadState(i);
                next.@Lock();
                try
                {
                    if (Debugging.AssertsEnabled) Debugging.Assert(!next.IsInitialized || next.dwpt.deleteQueue == queue,"isInitialized: {0} numDocs: {1}", next.IsInitialized, (next.IsInitialized ? next.dwpt.NumDocsInRAM : 0));
                }
                finally
                {
                    next.Unlock();
                }
            }
            return true;
        }

        private readonly IList<DocumentsWriterPerThread> fullFlushBuffer = new JCG.List<DocumentsWriterPerThread>();

        internal void AddFlushableState(ThreadState perThread)
        {
            if (infoStream.IsEnabled("DWFC"))
            {
                infoStream.Message("DWFC", "addFlushableState " + perThread.dwpt);
            }
            DocumentsWriterPerThread dwpt = perThread.dwpt;
            if (Debugging.AssertsEnabled)
            {
                Debugging.Assert(perThread.IsHeldByCurrentThread);
                Debugging.Assert(perThread.IsInitialized);
                Debugging.Assert(fullFlush);
                Debugging.Assert(dwpt.deleteQueue != documentsWriter.deleteQueue);
            }
            if (dwpt.NumDocsInRAM > 0)
            {
                UninterruptableMonitor.Enter(this);
                try
                {
                    if (!perThread.flushPending)
                    {
                        SetFlushPending(perThread);
                    }
                    DocumentsWriterPerThread flushingDWPT = InternalTryCheckOutForFlush(perThread);
                    if (Debugging.AssertsEnabled)
                    {
                        Debugging.Assert(flushingDWPT != null, "DWPT must never be null here since we hold the lock and it holds documents");
                        Debugging.Assert(dwpt == flushingDWPT, "flushControl returned different DWPT");
                    }
                    fullFlushBuffer.Add(flushingDWPT);
                }
                finally
                {
                    UninterruptableMonitor.Exit(this);
                }
            }
            else
            {
                DocumentsWriterPerThreadPool.Reset(perThread, closed); // make this state inactive // LUCENENET specific - made method static per CA1822
            }
        }

        /// <summary>
        /// Prunes the blockedQueue by removing all DWPT that are associated with the given flush queue.
        /// </summary>
        private void PruneBlockedQueue(DocumentsWriterDeleteQueue flushingQueue)
        {
            var node = blockedFlushes.First;
            while (node != null)
            {
                var nextNode = node.Next;
                BlockedFlush blockedFlush = node.Value;
                if (blockedFlush.Dwpt.deleteQueue == flushingQueue)
                {
                    blockedFlushes.Remove(node);
                    if (Debugging.AssertsEnabled) Debugging.Assert(!flushingWriters.ContainsKey(blockedFlush.Dwpt), "DWPT is already flushing");
                    // Record the flushing DWPT to reduce flushBytes in doAfterFlush
                    flushingWriters[blockedFlush.Dwpt] = blockedFlush.Bytes;
                    // don't decr pending here - its already done when DWPT is blocked
                    flushQueue.Enqueue(blockedFlush.Dwpt);
                }
                node = nextNode;
            }
        }

        internal void FinishFullFlush()
        {
            UninterruptableMonitor.Enter(this);
            try
            {
                if (Debugging.AssertsEnabled)
                {
                    Debugging.Assert(fullFlush);
                    Debugging.Assert(flushQueue.Count == 0);
                    Debugging.Assert(flushingWriters.Count == 0);
                }
                try
                {
                    if (blockedFlushes.Count > 0)
                    {
                        if (Debugging.AssertsEnabled) Debugging.Assert(AssertBlockedFlushes(documentsWriter.deleteQueue));
                        PruneBlockedQueue(documentsWriter.deleteQueue);
                        if (Debugging.AssertsEnabled) Debugging.Assert(blockedFlushes.Count == 0);
                    }
                }
                finally
                {
                    fullFlush = false;
                    UpdateStallState();
                }
            }
            finally
            {
                UninterruptableMonitor.Exit(this);
            }
        }

        internal bool AssertBlockedFlushes(DocumentsWriterDeleteQueue flushingQueue)
        {
            foreach (BlockedFlush blockedFlush in blockedFlushes)
            {
                if (Debugging.AssertsEnabled) Debugging.Assert(blockedFlush.Dwpt.deleteQueue == flushingQueue);
            }
            return true;
        }

        internal void AbortFullFlushes(ISet<string> newFiles)
        {
            UninterruptableMonitor.Enter(this);
            try
            {
                try
                {
                    AbortPendingFlushes(newFiles);
                }
                finally
                {
                    fullFlush = false;
                }
            }
            finally
            {
                UninterruptableMonitor.Exit(this);
            }
        }

        internal void AbortPendingFlushes(ISet<string> newFiles)
        {
            UninterruptableMonitor.Enter(this);
            try
            {
                try
                {
                    foreach (DocumentsWriterPerThread dwpt in flushQueue)
                    {
                        try
                        {
                            documentsWriter.SubtractFlushedNumDocs(dwpt.NumDocsInRAM);
                            dwpt.Abort(newFiles);
                        }
                        catch (Exception ex) when (ex.IsThrowable())
                        {
                            // ignore - keep on aborting the flush queue
                        }
                        finally
                        {
                            DoAfterFlush(dwpt);
                        }
                    }
                    foreach (BlockedFlush blockedFlush in blockedFlushes)
                    {
                        try
                        {
                            flushingWriters[blockedFlush.Dwpt] = blockedFlush.Bytes;
                            documentsWriter.SubtractFlushedNumDocs(blockedFlush.Dwpt.NumDocsInRAM);
                            blockedFlush.Dwpt.Abort(newFiles);
                        }
                        catch (Exception ex) when (ex.IsThrowable())
                        {
                            // ignore - keep on aborting the blocked queue
                        }
                        finally
                        {
                            DoAfterFlush(blockedFlush.Dwpt);
                        }
                    }
                }
                finally
                {
                    flushQueue.Clear();
                    blockedFlushes.Clear();
                    UpdateStallState();
                }
            }
            finally
            {
                UninterruptableMonitor.Exit(this);
            }
        }

        /// <summary>
        /// Returns <c>true</c> if a full flush is currently running
        /// </summary>
        internal bool IsFullFlush
        {
            get
            {
                UninterruptableMonitor.Enter(this);
                try
                {
                    return fullFlush;
                }
                finally
                {
                    UninterruptableMonitor.Exit(this);
                }
            }
        }

        /// <summary>
        /// Returns the number of flushes that are already checked out but not yet
        /// actively flushing
        /// </summary>
        internal int NumQueuedFlushes
        {
            get
            {
                UninterruptableMonitor.Enter(this);
                try
                {
                    return flushQueue.Count;
                }
                finally
                {
                    UninterruptableMonitor.Exit(this);
                }
            }
        }

        /// <summary>
        /// Returns the number of flushes that are checked out but not yet available
        /// for flushing. This only applies during a full flush if a DWPT needs
        /// flushing but must not be flushed until the full flush has finished.
        /// </summary>
        internal int NumBlockedFlushes
        {
            get
            {
                UninterruptableMonitor.Enter(this);
                try
                {
                    return blockedFlushes.Count;
                }
                finally
                {
                    UninterruptableMonitor.Exit(this);
                }
            }
        }

        private class BlockedFlush
        {
            internal DocumentsWriterPerThread Dwpt { get; private set; }
            internal long Bytes { get; private set; }

            internal BlockedFlush(DocumentsWriterPerThread dwpt, long bytes)
                : base()
            {
                this.Dwpt = dwpt;
                this.Bytes = bytes;
            }
        }

        /// <summary>
        /// This method will block if too many DWPT are currently flushing and no
        /// checked out DWPT are available
        /// </summary>
        internal void WaitIfStalled()
        {
            if (infoStream.IsEnabled("DWFC"))
            {
                infoStream.Message("DWFC", "waitIfStalled: numFlushesPending: " + flushQueue.Count + " netBytes: " + NetBytes + " flushBytes: " + FlushBytes + " fullFlush: " + fullFlush);
            }
            stallControl.WaitIfStalled();
        }

        /// <summary>
        /// Returns <c>true</c> iff stalled
        /// </summary>
        internal bool AnyStalledThreads()
        {
            return stallControl.AnyStalledThreads();
        }

        /// <summary>
        /// Returns the <see cref="IndexWriter"/> <see cref="Util.InfoStream"/>
        /// </summary>
        public InfoStream InfoStream => infoStream;
    }
}


It is already known that the best food in Spain is in the north and in Galicia, due to its geographical location and the quality of the products, it is surely the right place for those who love good cuisine.
We have good restaurants in Outes, with a wide variety of gastronomic offers that ensures that anyone who visits us can enjoy a good plate of food. We are going to propose some options and you can choose the one that appeals to you most.
The Galician rias are very rich in terms of fish and shellfish production, in fact, our region is the main producer of the country. The ria of Muros and Noia, where we are located, stands out for the gathering, above all, of cockles and clams, but in its marine depths we can find an almost infinite biodiversity. Two of the best restaurants in the area located on the dock of O Freixo, our humble but profitable fishing port, benefit from this.
The first stop is Restaurante Pepe do Coxo , a perfect place to taste all the richness of our waters. You can enjoy a wide variety of dishes, with the freshest products you will find.
Just a few meters away we find Restaurante Ríos, offering us a menu full of delicacies. The base is the same as in the previous case, fresh, high-quality products, but with a more sophisticated touch.
These two restaurants offer us a big bonus: the wonderful views of the ria from the large windows in their dining rooms, which will make our meal more special.
Although Galicia is a powerhouse when it comes to fish and seafood, we are also great lovers of meat and we have one of the most prestigious designations of origin today, Ternera Gallega (Galician Veal). It stands out for its intense and pleasant taste with an extraordinary tenderness, juiciness and succulence, aimed at the most exquisite and demanding palates.
At Restaurante Areal, located only a few meters away from our Cabañitas del Bosque, they know a lot about this. Their specialty is grilled meat, and we can assure you that if you are looking for quality meat, you are in the right place. One cannot only live off beef, so they also have Iberian pork of the highest quality, as well as other types of dishes such as cod, pizzas, etc.
If what you are looking for is traditional Galician cuisine, with products from the garden and traditional dishes from here, like caldo gallego (Galician soup), empanada, etc., but without giving up good meat or a good Galician fish, we also have some options for you.
Very close to our cabins, Restaurante Casa de Roque offers you a high quality menu at more than reasonable prices. In addition, the place itself is very nice, beautiful and quiet, with a typical Galician stone building and a spectacular natural environment.
Finally, and looking a bit after ourselves, we want to recommend to you Casa Perfeuto María, our rural boarding house. Our dining service offers our guests homemade traditional regional cuisine, following the "zero kilometer" philosophy, with products from the land and sea. In the small dining room of the house, you can taste the most exquisite dishes of the abundant and varied Galician cuisine, always prepared for the occasion upon prior reservation.
Depending on the season, we use vegetables and other products from the organic fruit and vegetable gardens of the neighbors of our village.
One more reason to visit Outes.


How to install my Philips KEY camcorder?
The PHILIPS KEY camcorder supports USB Mass Storage Class. When you first connect the camcorder to a PC running on Windows ME, 2000 or XP via the USB connector, an application will launch to recognize the camcorder as a USB Mass Storage Class Device. Your camcorder is detected as ?New Hardware? and will be listed automatically as a ?Removable Disk? in Windows Explorer, so there is no need for you to actually install a separate driver. IMPORTANT! For PCs running on Windows 98, a separate driver has to be installed BEFORE hooking up the camcorder with your PC. Please install your driver by following the steps below: 1. Please make sure that you have about 50MB of free space in the hard disk of your computer, if not please delete some of the files before doing the installation. Insert the installation CD into the CD-ROM drive. 2. An application will run automatically in the background checking whether a driver has been previously installed on your computer. Driver installation for your camcorder will start automatically if no previous driver is detected. (If the application fails to launch automatically, try opening and closing the CD-ROM tray to kick-start the application) Or open the CD-ROM in explorer, find the fscommand folder and double click Win98_setup.exe to run the driver installation 3. Once the driver is installed, you can hook up the camcorder to your computer for downloading of music via Windows Explorer.


text:
Aardwolf Press
We publish books. Occasionally.
"Chasing Fuseli," by Darren Speegle
Chilled, dejected, resigned, I lamented the sound that preceded the train. I'd prayed halfheartedly that by some stroke of fortune the last run of the day had been canceled, that the mist enshrouding the narrow Lauterbrunnen Valley would remain undisturbed until it chose to abandon the rushing mountain stream that was its source. Of course in the dream I wasn't fortunate either. In the dream the train arrived precisely at 9:44, according to the clock that stood above the empty station.
The bundle in my arms, emitting a stench of alcohol, weighed on me. I looked back along the road, locking the image of the wheelbarrow into my memory, a keepsake of this awful night. The wheelbarrow might have been sitting there since last fall, so idle and useless it seemed. My eyes wandered across the stream and up the hillside till they found the lights of the cabin peering out of the mist. I wondered if within those walls the dream kept going, though the cabin was empty. I let my gaze continue up the slope, beyond the sheep pen, above the waterfall, to the snow-covered firs growing at the brink of the sheer cliff. Above the trees, crisply configured against the moonlit night, stood the mighty Jung-frau and Eiger, treasures of the Alps. Just three days ago we had been skiing somewhere up there. But then . . . then the thing had culminated with a ferocity to which even the master's brush mightn't have aspired.
I turned my attention to the station in time to see the train part the fog and come to rest by the desolate platform. A lamp stood by, casting a somber glow over the double metal doors of the first car as my heart—what was left of it—tick-tocked in raw, agonizing anticipation.
Fuseli dreamed.
That was when I knew it was going very, very bad for me. I lucid-dreamed that I was Fuseli dreaming, and it was so viciously real that when I woke I thought for a moment I was Fuseli.
"We've got to get you help, Gordon," Dana said to me.
I looked down at my chest, where she had placed her hand. It was moist with sweat. The hand I put over hers trembled.
"Do you want to tell me?" she said.
"Yes. It's better if I tell you."
We were at our Brunnen cabin by then. It was supposed to have been an escape from the nightmares and ghosts in Zurich, but now it was becoming clear: to the ragged ends of the Earth, they would never relent.
The corridor seems endless. The canvases that hang on both walls shimmer, as if with fresh paint. The carpet beneath my shoes rolls ahead of me, into darkness. I seem to carry what light there is with me, bringing the oils to life as I come. I recognize the paintings. I have envisioned these scenes, dreamt these scenes, even painted these scenes with my own brush. To my right, three witches point along the corridor toward whatever lies at its end. To my left, Lady Macbeth. Ah, and there she is again, with Banquo and the hags on the heath. And there—there is Thor in the boat of Hymir. And on the other side, Cardinal Beaufort. And . . . but there seems no end to these creations of mine.
I look down the length of the corridor and frown to see a dim light. I know it is an end at last, but the sight of it stirs something in me, a sense of familiarity and dread. I walk more slowly, considering whether or not I wish to continue, but now the light is moving toward me. Is it someone coming? Is it . . .
It is a door. I tell myself, do not touch it. But I'm dreaming— what harm can be done? A voice within me says, But are you dreaming?
I touch the door. I open it. Oh no, oh my God, my God, I knew but I could not stop myself. The words are caught in my throat. What are you? What are you and why are you torturing my innocent, sweet Anna?
"And you actually recognized her as Anna?" Dana watched me intently.
"I knew her, Dana. I knew the woman lying on that bed. She was Anna Landolt. It was as though I were watching a scene from my life."
"Which perspective?" she said.
"Detroit. That's the one that haunted him. That's the image he saw."
Detroit referred to the Detroit Institute of Art—as opposed to the Goethemuseum in Frankfurt, Germany. What I dreamed was not just a nightmare, it was The Nightmare, Henry Fuseli's Romantic-era masterpiece, and whether it manifested itself as the first version or the second, there was no escape from it.
"But it makes no sense," Dana said.
"What the hell does?"
"I mean, it being a scene from your life—Fuseli's life. Demons don't exist, Gordon. There was no such scene in Fuseli's life."
I fell in love with the The Nightmare when I was dating a girl who worked at a gallery near Purdue University, where both of us were students. I was no connoisseur, just a kid with an unsophisticated, college-taught knowledge of the Arts and a taste for their darker samples. Fuseli's depiction was certainly that. As I told Dana when we got to see the original in Detroit, The Nightmare is to painting what Dracula is to literature.
Although I came to regard the work as my single favorite artistic piece in any medium, I didn't obsess over it as in fact I had with Stoker's novel in my younger years. On the contrary, I might never even have viewed the work if Dana and I hadn't been in Detroit for a writers conference. Our winding up in Vienna, too, was by pure coincidence. Dana accepted a job with the World Wildlife Fund, and there I found myself, in the very city where Sigmund Freud had hung an engraving of Fuseli's masterpiece in his apartment. It wasn't until a year later, when Dana was transferred to Switzerland, no less than the birthplace of one Johann Heinrich Füssli, aka Henry Fuseli, that I began to wonder . . .
I dreamed of the painting our first night at the hotel in Zurich. On waking I rationalized about associations being at work. Fuseli had been a topic on the drive down from Vienna, when I had noted to Dana the irony of our life's course. She had admitted the coincidences were odd, but that's as far as she would go with it.
"Chasing Fuseli," she called it. "Like something out of one of your novels. Or worse yet, those twisted films you watch."
I had rented Bergman's Hour of the Wolf recently and Dana had had her own nightmares.
"Well, if I'm chasing Fuseli, I'm chasing him backwards through time. But I guess that's the way we chase ghosts."
I thought about this dialogue as I disentangled myself from the cobwebs of my disturbed sleep. It was the dead of night, the November air penetrating the high arched windows of the fourth-floor hotel room, and Dana slept right on through, as if I hadn't just dreamed of Fuseli's nightmarish vision, and indeed, of the artist himself. He was a more squat, malevolent-looking rendition of the man whose face I had managed to memorize along the way, but definitely Fuseli— my dream-sense said so.
Just as the incubus did with the woman in The Nightmare, he had been crouching on Dana's belly as she lay sprawled across a bed in the throes of an erotic nightmare. Peering from out of the curtains behind her was the ghastly head of the steed that bore the incubus through the night.
Strangely, as I experienced the horrific image in my dream, my perspective was that of Fuseli's second version of the painting, the one that hung in the Goethemuseum in Frankfurt, the one that I thought far inferior to its predecessor. I say "strangely," because I never even vaguely referenced the second version when I brought The Nightmare to mind. I did know something about the first painting that might have encouraged my imagination's modifications of the image, however.
Fuseli was known to have fallen in love with one Anna Landolt, only to have his heart broken when she rejected his offer of marriage. On the back of the original painting in the Detroit Institute of Art was the portrait of a woman art historians believed to be Anna. Many agreed that if it was indeed she, then the demon haunting the woman in The Nightmare might very well have represented Fuseli himself. Because I had always been fascinated by this possibility, it wasn't unreasonable to assume—in a world where dreams made perfect sense—my mind might conceive of his face on the body of the incubus. The thing was, dreams didn't make sense.
I thought to wake Dana and tell her all about it, but decided I would be accused, with more sympathy than I could, uh pardon me, stomach, of taking this "Chasing Fuseli" a wee bit far.
Chasing Fuseli. Ha! Fuseli was chasing me.
The dream graciously proved not the recurring type—not then, that is. Dana and I spent the next few nights making our own startling images. We called it a vacation, though the days were spent looking for a house to rent, getting to know our way around, and, in Dana's case, familiarizing herself with the office and her new duties. Because the WWF's studios were on the skirts of the city, we were able to go rural in our house search, unlike Vienna, where our apartment overlooked the Opera House in the middle of the city. We found a place nine days after our arrival, pulled our stuff out of storage—touring Europe via an outfit like the WWF, which relied wholly on donations and subsidies, you trailered what you had, and you didn't have much—and cozied in among the cattle and sheep.
Between hikes and local bike tours, my exercises of choice, I spent my days writing, and my evenings trading the day's events with Dana, who loved her job every bit as much as I loved mine. Winter came and went, I dreamed tolerable dreams, and in the spring there was a writers conference in Frankfurt.
Dana teased me, but we went right to the Goethemuseum. The "other" view was much better than the cheap prints (and cheaper critics?) had made it out to be. The perspective painted nine years after the first was almost as disturbing, almost as erotic, almost as delicious to the darker tastes. Like most of Fuseli's work, it was somewhat overblown and lacking in subtlety, but God help me, I loved the man for these very merits. As William Blake said of him, Henry Fuseli was "The only man that e'er I knew/who did not make me almost spew."
I went home from that conference happy. I had had no expectations, and look what Mr. Fuseli, Romantic that he was, had managed—the quelling of my layman preconceptions.
The night of our return, I dreamed of The Nightmare again. The perspective was that of the first version of the painting.
The next night I dreamed. And the next. And the next and next and next. Sometimes I dreamed one version, sometimes the other, sometimes my own variations. It wasn't until the eighth night running that it became so violent Dana was stirred from her own slumber.
She had heard me in its throes. When I woke, she remembered some of its fiercest parts for me.
"You said you were going to rip the heart out of me and feed it to your horse." Apparently the subject matter of the dream, which I vaguely remembered myself on this occasion, was lost on her.
"I did not say that."
"And you said you were going to dip your paintbrush in my blood."
"Did I actually speak your name?"
"'I'm going to dip my paintbrush in your blood, Dana.' Those were your words."
It was crazy, nonsensical, not to mention perverse. Fuseli and the demon seemed interchangeable in my unconscious mind. "God, Dana, I'm sorry."
"No, no. No need. But if any of your future conferences ends up near one of Mr. Fuseli's paintings, we'll skip it, mmm?"
"What else did I say?"
"You said I was a demon's whore, your whore, and that I should remember that."
"Jesus."
It was that night, I think, that I first allowed myself the bizarre notion that I was possessed by Fuseli. Ghost or reincarnation.
I did not speak this to Dana. I never spoke any such thoughts to Dana until the last night in Brunnen, when we sat by the hearth, in the glow of the fire and the cognac.
Dana said something to me, and unbeknownst to us both, the end was beginning.
"Why don't we take a vacation, Gordon? We haven't gone skiing since Austria. They were just talking at the office about how fantastic the skiing is in Switzerland. What do you say?"
"I think that's a great idea, Dana. I do."
A month later we were in the gorgeous Lauterbrunnen Valley.
During that month before we packed up our skis, neither of us commented on the weight I had lost, on my hair seeming to gray and thin, on the haggard face I regarded in the mirror each morning. I entertained the thought that maybe Dana didn't see it. Or maybe she attributed it to difficulties I was having with my novel-in-progress. One day I remarked that I wished I had never quit smoking. That evening she brought a joint home from work, courtesy of the secretary. "It's not tobacco," she said, "but maybe it will make you feel better." That was as close as she came to commenting on my condition.
When the day came, and we loaded up the Opel wagon, I found myself feeling better, looking forward to getting out. My hikes and bike tours had diminished to practically nil. I even brought along my laptop, which Dana, under any other circumstances, would have been bitching her head off about. This time, anything that bore a semblance to normalcy was okay. She knew. She knew I had been under a slow, twisting knife, dying from within.
Our journey took us by way of Interlaken, which only served to further brighten my spirits. It was said the water of the sibling mountain lakes was among the purest in the world, the fish that came out of it second to none. Mid afternoon found us dining by the clear water, in the shadow of the mountains whose snows fed the lakes, and the fillets, as advertised, were the best we had ever tasted. I kissed her over white wine, making my wife of eight years actually blush. It seemed a long time since we had done that—kissed for any reason.
We drove twenty kilometers south through the narrow, deep cut in the Alps that was the Lauterbrunnen Valley. As we approached the village of Brunnen, we watched both slopes for a cabin we had seen only on the Internet. We had to turn around ultimately, so overwhelmed by the beauty of our surrounds that we could not possibly have picked out our little cabin. At the Bahnhof they instructed us how to get there. This side of the big waterfall . . .
"Not that one!" exhaled Dana. "The photo did not do it justice!" I took her hand, and we passed a face on our way out. It looked like Henry Fuseli's.
That particular injury may have been the hardest to overcome.
As usual I said nothing to Dana. I listened to her go on about the cabin as we drove up the hill. I smiled. I participated as best I could. But by the time I engaged the emergency brake, she had sensed the change in me.
We unpacked silently. When our eyes happened to meet, I saw the sympathy pouring out of her. It was only a matter of time before that emotion would be joined by fear and confusion and even anger. We are all built to react that way.
It came that night, down in the village, over Salat and Brötchen, a lighter dinner after the late, satisfying lunch we'd spent.
"You know, Gordon, this . . . whatever it is . . . is beginning to hurt our marriage. I have tried to be patient. I have tried very hard. I don't know what happened earlier, but you're on a path that's not just going to destroy you, but us as well. I'm involved, you know. You look in the mirror and feel sorry for yourself, but I—me, Gordon—I'm involved too."
"I know," I said stupidly.
"We're here, it's beautiful, an absolute wonderland. But you . . . you've fucked it up again."
"Again?" I echoed.
"Every time we seem to be making strides."
"You make it sound as if I'm trying to overcome an addiction."
She let her head fall to the side slightly, stared fixedly at me.
"I don't know what's wrong with me," I said. The beer tasted bitter as I tried to clear the dull haze that had followed me from the Bahnhof.
"I don't know what's wrong with you either."
"I'll come out of it."
"Will you?"
Silence reigned for the better part of dinner. The waitress, in her quaint, made-for-tourists Swiss outfit, felt the mood. Feeling the mood, her English grew deliberately poor. Her face fell each time she came within ten feet of our table, a chore she tried to avoid even when our glasses sat empty. I almost had to shout for the bill—and Rechnung does not sound pleasant off my baby tongue—when it came time to pay.
After settling up, Dana and I strolled the village. The sun set on us as we shopped windows and their baubles. Sounds of merrymaking drifted from a nearby campground. A rollerblader shot by, glancing back at me to show me his straight Fuselian nose by the light of a streetlamp. A net of stars dipped in the deepening liquid of night.
It would be like this each night, wherever we were, only worse.
The next night, as we descended by rail from the slopes, I called my wife Anna.
"What?" Her mouth was open, and her eyes were inside me, every bit as cold and steely as the knife that always twisted. The train bore at a steep downward angle, gravity playing hell on my body and mass.
"I don't know why I—" I threw up, all over my boots, all over the seat in front of me.
She pitied me. As I looked around, wondering if anyone had heard, if anyone had seen—the seats immediately surrounding ours were empty, perhaps owing to the gloom that hung around us—she pulled an extra sweatshirt from her bag and began to mop it up.
"We've got to get you help," she whispered.
"I . . . I had too much to drink."
"You had two beers, Gordon. Three hours ago."
"I'm sorry. I'm sorry, Ann—" Too late. I'd done it again.
She hit me in the chest. A terrible taste filled my mouth. A terrible smell filled the air.
We got off at the next stop, though it wasn't the bottom. Dana stuffed the sweatshirt in a garbage receptacle. Faces peered out at me from the train. They all knew. They all had long straight noses and a penchant for drama and symbolism.
Dana wanted to know if I was ready to go back to Zurich. I told her to take the next train down, I wanted to walk for a while. I was backing away as I spoke. She started to protest, but then she let me go.
We were still well above the snow line, so I had a time finding the trail out of the little tourist village where the train had deposited us. Finally I did, and in shin-deep snow, I made my unhurried way down the mountain. When I reached the valley, I was desolate, empty. By the rushing river, at the dead station, I curled up on a bench and slept.
I sleep in the night, on a wooden bench. The moon is new, but the stars are countless. The river rushes, foamy and brilliant, music to die by.
My eyes are open as I lie here, and I see someone on the footbridge, coming my way. It doesn't look like a man, but a boy, or perhaps a woman, small and squat, old. What can she want of me as she steps from the bridge, turning in my direction?
What have I to offer an old woman?
But I now recognize it is not a woman. It is not a boy. It is not human. It is stumped and beastly, and horribly grim in the gesture of its claw. It belongs in lower places, not here, not in beautiful Where I am.
Where I am.
It wants something from me, but what have I to offer a demon?
Anna, it says. She is mine.
"What, what—?"
"You're dreaming again," she said.
"Isn't it cold? Who . . . ?"
"It's Dana."
"Dana. Yes . . . "
"Let me get you something," she said.
"Sleep. Sleep is what I need."
I drift into a corridor. It seems endless. Canvases on both sides shimmer with fresh paint.
"I'm so afraid for you," came the tendril of Dana's voice.
To my right, three witches point along the corridor toward whatever lies at its end. To my left, Lady Macbeth. Ah, and there she is again, with Banquo and the hags on the heath.
"Wake up . . . "
I ignore the voice. I am touching the door. I am opening it. Oh no, oh my God, my God, I knew but I could not stop myself. The words are caught in my throat. What are you? What are you, and why are you torturing my innocent, sweet Anna?
"Wake up, wake up. Gordon!"
I started beneath the flat of her hand.
"Are you—?"
"I'm Dana, Gordon."
"I . . . was Fuseli dreaming. I knew I was dreaming, but I knew it as him." I looked down at my chest, where she had placed her hand. It was moist with sweat. The hand I put over hers trembled.
She listened, and I told her.
"And you actually recognized her as Anna?"
"Which perspective?"
I stared. "Which—?"
"Perspective."
"But we haven't discussed my nightmares except that one time . . . "
"That one time when you said you would dip your paintbrush in my blood."
"Did I speak of . . . perspectives?"
"With your brush you did. Your brush, my blood, in the mirror."
"Did I—"
She showed me her tongue, with the deep teeth marks in it.
"I would never do that to you, Dana . . . "
"Wouldn't you?" she laughed, throwing her head back and letting her tongue loll from her mouth.
I threw the covers off me, rolled off the bed, looked back—
There he was, upon her belly, as she twisted in the erotic nightmare that gripped her.
And yet it was Dana saying, "It makes no sense . . . A scene from your life? . . . Demons don't exist . . ."
The last day, I woke late. The dream was fresh, unabating. I would carry it with me all day.
"What shall we do today?" she asked cheerfully.
What had I done to make her think the end hadn't arrived? Maybe she knew it was the last day, and was grateful.
Over Brötchen and cheese and soft-boiled eggs, we talked about how pleasant life really was, how fortunate we were to be in Europe, and in Switzerland specifically, lovers of nature that we were. How fortunate we were to know their traditional breakfast of Brötchen and cheese and soft-boiled eggs.
"I think we should stay close to the homestead today," I said.
"Do you love me?"
"I do, Dana."
"You wouldn't go back to Zurich without me, would you?" She laughed as she said it, but I wondered.
There was a falls a few kilometers south of the village of Brunnen that was touted as carrying a higher volume of water than any other waterfall within a mountain in the world. We decided to hike to it, do the ascent through the water-carved rock, and hike back. Once upon a time, that would have spelled paradise to me. Now it spelled the motions of the last day. I told Dana I loved her four times as we explored the falls.
But still I didn't die.
"Tonight," she shouted over the roar, "I want the richest, most expensive, most sinful dinner we can find." It was Saturday. All the restaurants would be open.
We took the suggestion of a proprietor and did a place that had appeared in the film, The Eiger Sanction. The choice, tender portions we received certainly merited that sort of stardom. They served cognac, and we drank cognac. It was the color of Dana's hair.
Night fell during our return. She had insisted I buy a bottle for the road, though the road amounted to but four kilometers. We drank as we walked; the sky grew less clear, a mist evolving of the river-stream that cut the valley.
"You could toss me in, and never have to worry about me again," she said.
"Is that something you've thought about?"
"Maybe." Still laughing, amber laughter.
"Do you think I would do such a thing?"
"I don't know you well enough to know, do I?"
It would be easy, I thought, as I looked at her, half-drunk wife of mine. But I envisioned the incubus hanging from the footbridge to snatch her up as she swept downstream.
When we reached the cabin, we fetched glasses, emptied the rest of the bottle. Before the hearth we sat, sopping and hopeless, and made short, furious love by the flames.
I lamented the sound of its coming even then.
Chilled, dejected, resigned, I lamented the sound that preceded the train. The noise of the rusty wheel of the wheelbarrow hung with me. The stench of alcohol was pungent, but that was goodness and mercy, not a forerunner of the abominable act being committed. Little that it mattered. It was 9:44, and she was a demon's whore.
As the doors parted, wrenching open the night itself, I begged her, without looking down at her face, to forgive me. A dark horse and rider emerged. The bearer of the incubus, eyes aglow, snorted and blew in the misty night. The clop of its hooves, as it majestically bore its inhuman rider toward me, was my heartbeat. Within a few feet, the noise stopped.
The incubus and I stared down.
"The whore," the demon gestured.
"Why?" I said, meaning all of it, every bit, the nightmares and the rest.
"My whore!" he lashed.
I stood there with her weight in my arms. "And Fuseli?"
"Bah. She was always my whore. He just caught us at it."
"I've loved this woman," I stated.
"You may have loved her, you may have made love to her, but she was never yours." The incubus shook its unseemly head, tapped its chest. "She has always been mine."
"What will you do with her?"
"What do you do with yours, mortal?"
The decision descended on those words. "I look at you, demon, and I find I have at least enough for this one last thing."
And I lunged for the river, my bundle in my arms. As I tossed it, he screamed. But it was a rueful scream, which gave me hope. A last hope.
They rode the river, horse and rider trailing wings of hell, and I started back for the cabin, shoving the wheelbarrow aside as I stepped onto the footbridge.
She was there on the bed as I entered, tossed across the draping sheets in the throes of an erotically violent dream, her hands caressing her breasts, her belly, clutching at the fabric of her gown. Moaning a name unspeakably vile to my ears.
Dana for that moment, and then . . .
Gone. The smell of cognac and ashes and sex lingering. Her tongue crawling out of nothing to touch at the residue of my clumsy strokes against her, against my own nightmares, against the devil rider. Whichever perspective he chose.

redpajama_set_name: RedPajamaCommonCrawl


Vintage Christmas Lawn Decorations Awesome 461 Best Christmas Yard Art Images is free HD wallpaper. This wallpaper was upload at January 23, 2018 upload by bestedpillsonline in Craft.
Description: Vintage Christmas Lawn Decorations Awesome 461 Best Christmas Yard Art Images from the above resolutions which is part of the Craft. Download this image for free in HD resolution the choice "download button" below. If you do not find the exact resolution you are looking for, then go for a native or higher resolution.
New Vintage Christmas Lawn Decorations - From the thousands of photographs on-line regarding vintage christmas lawn decorations, picks the very best libraries together with greatest quality simply for you, and this pictures is actually among photographs libraries within our greatest photos gallery concerning New Vintage Christmas Lawn Decorations. I'm hoping you might want it.
This kind of impression (Vintage Christmas Lawn Decorations Awesome 461 Best Christmas Yard Art Images) above is actually branded with: all for you.
Placed by simply bestedpillsonline at 2018-01-23 16:49:02. To see most images throughout New Vintage Christmas Lawn Decorations graphics gallery remember to follow this particular link.
Download Vintage Christmas Lawn Decorations Awesome 461 Best Christmas Yard Art Images with original resolution Click Here!
22 Photos of "Vintage Christmas Lawn Decorations Awesome 461 Best Christmas Yard Art Images"
Related Posts of "Vintage Christmas Lawn Decorations Awesome 461 Best Christmas Yard Art Images"


1. I saw law professor (and newly-minted Washington Post blogger) Eugene Volokh do a fine job criticizing gun control at an NYU Federalist Society debate yesterday (a reminder that I promise to replace the debates I've long hosted with other fun events to be announced in the near future).
2. If the fundamental right to self-defense doesn't resonate with you when you contemplate guns, try mulling the principle while reading this Mark Steyn piece about rising anti-Semitic violence (h/t Baruch Gottesman).
3. In other foreign affairs news, I hope you read my letter in the Wall Street Journal a couple months ago on whether to merge the U.S. and Canada.
4. None of the above is quite as strange, though, as news of a woman in China duping people by pretending to be a male cop with superpowers.
5. I'll be at the Wall Street Journal offices tomorrow, as it happens, visiting along with a three-times-a-year gathering of my fellow Robert Novak Fellows, an assortment of conservative and libertarian writers.
We gathered in the old Journal offices once, and my favorite part of that meeting may have been learning that an old stock-ticker-tape machine still sat in one corner of the editorial boardroom, a rather steampunk reminder that Dow Jones was technically an electronic communications company over a century ago, before it owned a newspaper.
6. Columnist Tim Carney (who was good on the Feb. 17 episode of The Independents) is one of the Novak Fellows, whereas his brother John Carney just joined the Journal, and two weeks later brother Brian Carney left the Journal, for those struggling, as we all have at times, to keep track of Carney brothers.
Inevitably, they sometimes make me think of this song. And that song is not as creepy as this unusual photo of the man singing it, Nick Cave, wearing a Scooby-Doo costume. If you combine Nick Cave and Echo and the Bunnymen's Ian McCulloch, to my delight you sort of get the current band the Editors, who have several neat songs like this.
7. The best way to combine the Novak Fellows experience with music, though, is to see one of them perform Saturday at 6:30 (International Arts Movement, 38 W. 39th, 3rd floor), namely Jesse James DeConto with his band Pinkerton Raid.
8. After such revels, we will still need serious political writing, though, such as this Journal item on (ex-Sandinista) Mayor de Blasio's campaign against charter schools.
9. In other de Blasio news, Julia Kamin notes his NYPD has issued 215 summons for jaywalking -- yes, jaywalking, which no New Yorker considers a crime -- in just over a month in early 2014, part of de Blasio's crusade to reduce traffic deaths while ticketing cars less.
I guess we won't have to worry about being run over by the carriage horses de Blasio's banning either (and it sounds suspiciously like his motivation there had less to do with horse wellbeing than with a de Blasio donor wanting the horses' building after the unemployed horses vacate it).
10. You almost can't blame people for thinking politics is wholesome and high finance corrupting, though, when you read things like this account of decadent, secret Wall Street parties (h/t Ivan Cohen). And then there's the strange wave of apparent suicides among JP Morgan employees (not that one can't find all that creepy and be alarmed by public-sector goings-on, such as Democrats stealing voter-registration information for campaign purposes in Texas...or the Obama administration planning increased use of government minders in newsrooms...or...or...).
But when the world seems filled with corruption and cronyism, there's always this cute kitten sitting in a glass as a distraction -- or this Matrix-like berserk-kitten fight sped up and set to techno music. Would that all conflicts were as simple.


Can't find the exact Kit you need?
Well choose a hard kit case or a soft bag and fill it with what you want. Below are all the details you need to decide, then have a browse though the tungsten kits and see what we have put in our selection then just mix 'n' match!
When you come to order, if we think there is something amiss we'll mention it. After all Photon Beard is famous for it's service.
to make them secure. The tongue and groove lid joint gives strength and resists dust and moisture penetration. All interiors are foam padded and feature movable padded partitions, with accessory pockets and straps to hold brollies etc. The larger cases are fitted with wheels for ease of movement.
fitted with movable partitions. These cases are fitted with padded carrying handles and adjustable shoulder straps.


Monday 3rd July marked the official opening of CCAF Solar Energy Project, a significant event for the whole AMATIL Group. CCAF and Sunergise Fiji & New Zealand have entered a partnership for the installation of more than 3,800 solar panels to the Suva production plant which provides a 40% cleaner renewable energy source.
The launch was officiated by the Honourable Prime Minister Voreqe Bainimarama who saluted the company's vision on behalf of all Fijian and encouraged every Fijian business and investor to consider following CCAF's example. The Honourable Prime Minister went on to say that what CCAF has done is a practical and highly effective way in which the private sector can make it's own contribution to the fight against climate change. He said, 'it really is a potential game changer; solar technology is becoming increasingly more efficient as well as affordable; and this is something that can be replicated throughout the region'.
"This Solar Energy Project is the first of its kind in the AMATIL family and is something we are very proud of as it aligns with our environmental values. We take our Corporate Social Responsibility very seriously and support the Fiji Government's efforts to encourage a more resilient Fijian community and economy by addressing the global impacts of climate change" said Roger Hare.
Present at the launch was Alison Watkins, Coca-Cola Amatil's Group Managing Director. "Our sustainability Framework focuses on four areas that are important to us and where we believe we can make the most impact – our people, Consumer wellbeing, environment and our community". This first stage of the solar project will provide 40% of our Suva site energy requirements and when Stage 2 comes online 80% of the site energy needs will come from the sun. A fantastic outcome for Amatil and the environment stated Alison. The project she said was another example of Coca-Cola Amatil team's commitment to further reducing the carbon footprint with the rollout of 1.1 megawatts of renewable energy generation. Sunergise Co-Founder, Ajay Raniga stated, Sunergise is delighted to partner with Coca-Cola Amatil to create the largest grid connected roof top installation in Fiji, New Zealand and the Pacific Islands. This 1.1MW solar system is equivalent in size to about 200 residential systems, consisting of over 3,860 solar panels and 39 25kW invertors. Producing 1,408,000 Kilowatt hours of energy per year, the system will save 974 tons of CO2 annually. This is equivalent of saving 414,722 litres of diesel per year, or avoiding 3,730,751 car kilometers annually or planting 24,964 trees.
CCA Fiji has been undertaking initiatives toward meeting goals identified around reducing refrigeration and manufacturing emissions utilizing solar energy, promoting sustainable packaging utilizing renewable and recycled content, and increased material resource efficiency. Recently CCA Fiji introduced Solar fridges to refrigerate products and have placed five in the market on a trial basis before further roll out.
Initial discussion of this project began with Coca-Cola Amatil's Head office in New Zealand and Sunergise. A feasibility study took place in November 2016 and works began on this project in March 2017. The now complete project consists of over 3,860 solar panels and provides 40% of the facility's total power supply.


text:
Home of the "Greatest Snow on Earth," Salt Lake City is a mecca of outdoor recreation. Seven major ski resorts are within an hour's drive of campus. In the summer, thousands of hiking and biking trails are easily accessible along the Wasatch Front and five of the nation's most beautiful national parks are located across the state. The University of Utah is located in one of the most diverse and exciting areas in the world. From world-class skiing in the Wasatch Mountains, to the beautiful sandstone deserts of southern Utah, even long-time residents can't get enough of their home state!
Utah is widely praised for its scenic beauty. Recreational activities like mountain biking, fishing, snowboarding, and skiing at eight world-class resorts are just a short drive from the University of Utah campus in Salt Lake City. Utah also boasts five national parks and more than 40 state parks that provide opportunities like hiking, rock climbing, whitewater rafting and camping. Meanwhile, Salt Lake City is home to professional sports teams such as Real Salt Lake and the Utah Jazz as well as the University of Utah's nationally-ranked football, basketball and gymnastic teams. There also are cultural gems to experience such as the celebrated Sundance Film Festival, Ballet West, the Utah Symphony, and one of the nation's largest and most successful Comic Con gatherings. And our reputation is only growing.
#1 Top Tech Meccas Looking to Overthrow Silicon Valley — Forbes
#1 Best Place to Start a Career — CNBC
#1 Best Place to Start a Career — WalletHub
#2 America's Next Boom Towns — Forbes
#3 America's 25 Best Cities for Young Professionals — Forbes
The U of U's induction into the PAC 12 strengthened the already active sporting community on campus. The Mighty Utah Student Section, or MUSS, is the student fan club for university athletics. It is also the most popular student section in the West. In addition to campus athletics, Salt Lake hosts an array of sporting events such as hockey, soccer, baseball, and professional basketball games.
About the U – The University Page
Living at the U – Housing on campus
Ski Utah – Official University of Utah Ski Page
Utah.com – Everything you could want to know about the outdoors
Salt Lake Area – Salt Lake City information, happenings, and more


The Cerro Calderico ridge and its twelve windmills: monuments in Consuegra, Toledo at Spain is culture.
Windmills such as these in Consuegra inspired Miguel de Cervantes to create the famous episode of the battle against the giants in his work 'Don Quixote'.
The Calderico ridge is a rocky outcrop which rises above the plain of La Mancha. This is the site of the La Muela or Consuegra castle, which is Muslim in origin but modified and extended during the 12th century by the Order of Saint John of Jerusalem. It has three defensive enclosures and has been restored in recent decades.
However this ridge is known above all because it is home to twelve of the thirteen windmills that originally stood here, all of which have been christened with names taken from the immortal work 'Don Quixote'. Four of them still conserve their machinery in good working order. The windmill known as Molino Sancho is particularly interesting and dates from the 16th century. It is used as the venue for the Consuegra Saffron Festival.


text:
John Donald Budge (13 de junho de 1915, Oakland - 26 de janeiro de 2000, Scranton) foi um jogador de tênis que se tornou famoso por ter sido o primeiro homem a ganhar em um único ano os quatro torneios que compõem o Grand Slam.

Budge entrou para o International Tennis Hall of Fame em 1964.

Em 2014, Budge foi um dos tenistas presentes na lista "Os 10 tenistas que transformaram a forma como o tênis é jogado", elaborada pela Revista Tênis. Segundo a revista, "''mesmo batendo com apenas uma mão (comum para a época), ele conseguia imprimir uma enorme potência, mas, mais do que isso, topspin. Apesar de outros tenistas antes dele já utilizarem o topspin, foi Budge quem aprimorou a técnica com seu backhand".

Grand Slam Finais

Simples: 7 (6 títulos, 1 vice)

Duplas: 7 (4 títulos, 3 vices)

Grand Slam Profissional

Simples: 8 (4 títulos, 4 vices)

Tenistas dos Estados Unidos
Naturais de Oakland (Califórnia)
Tenistas vencedores de torneios do Grand Slam
Membros do International Tennis Hall of Fame

redpajama_set_name: RedPajamaWikipedia


Andrew Strom is Associate General Counsel of SEIU Local 32BJ. This post is the next in a series of responses to Dmitri Mehlhorn's Daily Beast article and follow up post; Professor Jake Rosenfeld's responses are here and here.
Dmitri Mehlhorn has made two attention-getting assertions: (1) public sector unions have harmed the interests of the working poor; and (2) public sector unions have hurt the labor movement. While he claims that his assertions are "grounded in labor history and simple economics," in fact, his claims ignore history and are based on simplistic economics.
Taylor Rogers and Elmore Nickelberry were among the 1,300 who walked off the job in 1968. Rogers remembers picking up tubs of garbage that were full of holes. "That garbage would leak all over you," he says. By the time he got home, his clothes were dirty and full of maggots that had fallen on him. "I had maggots run down in my shirts, and then maggots would go down in my shoes," Nickelberry says.
Those sanitation workers went on a strike that was supported by Dr. Martin Luther King, Jr. after two workers were crushed to death because they had to ride in the barrel of a truck that malfunctioned.
Even today, many public sector workers are part of the working poor. Food service workers at public schools are often paid the minimum wage. The homecare workers at issue in Harris v. Quinn earned the minimum wage before they unionized. Even where public sector workers earn middle class wages, Mehlhorn is guilty of oversimplification. For instance, Mehlhorn complains about the cost of pensions for BART workers, but he fails to acknowledge that BART employees, like many public sector workers, are excluded from Social Security, so they desperately need their pensions in order to be able to retire with dignity. Likewise, his claim that poor Americans are harmed when teachers are laid off via Last-in, First-Out, is highly questionable.
Mehlhorn's economic claims are also suspect. He asserts that poor people who benefit from public services are harmed if public sector workers earn middle-class wages. But, this ignores the effect of public sector wages on the overall labor market. State and local governments directly employ over 19 million people. Private sector employers compete with government employers to attract and retain workers. When public sector wages go up, there is pressure on the private sector to raise wages as well. Likewise, any effort to drive down wages and benefits for public sector workers will exert downward pressure on private sector wages and benefits. Mehlhorn's attacks on public sector workers also divert attention from the real culprits who are harming the working poor. For instance, Mehlhorn suggests that in the Bay Area, residents must choose between middle class wages for BART workers and adequate funding for early childhood education. But given the fabulous wealth generated in that area, isn't the real problem that virtually all gains are going to a handful of people at the top of the economic ladder? To take another example, the best estimate is that states and localities spend $50 billion on tax incentives each year, bidding against each other to attract and retain businesses. Putting a stop to this arms race would go a long way toward funding public services.
Jake Rosenfeld has already ably responded to the claim that public sector unions harmed private sector unions by "sucking up the oxygen." But, I will add a couple of additional points. First, the assumption that unions would have done more private sector organizing in the 1960s and 70s if they hadn't been organizing in the public sector is questionable at best. In 1972, when AFL-CIO President George Meany was asked about the reasons for declining union density, he famously replied, "I don't know and I don't care." Second, Mehlhorn says that unions should focus more on organizing janitors and other low wage workers in the private sector. But, he conveniently ignores the fact that the union behind the Justice for Janitors movement, SEIU, is also one of the largest public sector unions in the country. SEIU's public and private sector membership do not compete with each other, but rather work together as part of the same fight for economic justice.


text:
package com.github.liosha2007.groupdocs.model.storage;

import java.io.Serializable;

public class MoveFolderResult implements Serializable {
    private String from_path = null;
    private String to_path = null;

    public String getFrom_path() {
        return from_path;
    }

    public void setFrom_path(String from_path) {
        this.from_path = from_path;
    }

    public String getTo_path() {
        return to_path;
    }

    public void setTo_path(String to_path) {
        this.to_path = to_path;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        MoveFolderResult that = (MoveFolderResult) o;

        if (from_path != null ? !from_path.equals(that.from_path) : that.from_path != null) return false;
        if (to_path != null ? !to_path.equals(that.to_path) : that.to_path != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = from_path != null ? from_path.hashCode() : 0;
        result = 31 * result + (to_path != null ? to_path.hashCode() : 0);
        return result;
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder();
        sb.append("MoveFolderResult");
        sb.append("{from_path='").append(from_path).append('\'');
        sb.append(", to_path='").append(to_path).append('\'');
        sb.append('}');
        return sb.toString();
    }
}

redpajama_set_name: RedPajamaGithub


Welcome to our online photo gallery, please select a category by clicking one of the tabs below.
Please click the photos to enlarge. Note! The larger photos will open on top of the page and you may navigate from one to the other by clicking on either side of the photo.
Photos partly provided by Mr J Images & Jane Harrison Photography. Aerial by Z Ten Media.