/*
 * Copyright 2014-2017 Real Logic Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.aeron;

import org.agrona.concurrent.AtomicBuffer;
import org.agrona.concurrent.status.AtomicCounter;

/**
 * Counter stored in the counters file managed by the media driver which can be read with AeronStat.
 */
public class Counter extends AtomicCounter
{
    private final long registrationId;
    private final ClientConductor clientConductor;
    private volatile boolean isClosed = false;

    Counter(
        final long registrationId,
        final ClientConductor clientConductor,
        final AtomicBuffer buffer,
        final int counterId)
    {
        super(buffer, counterId);

        this.registrationId = registrationId;
        this.clientConductor = clientConductor;
    }

    /**
     * Return the registration id used to register this counter with the media driver.
     *
     * @return registration id
     */
    public long registrationId()
    {
        return registrationId;
    }

    /**
     * Close the counter which will release the resource managed by the media driver.
     * <p>
     * This method is idempotent.
     */
    public void close()
    {
        clientConductor.releaseCounter(this);
    }

    /**
     * Has this object been closed and should no longer be used?
     *
     * @return true if it has been closed otherwise false.
     */
    public boolean isClosed()
    {
        return isClosed;
    }

    void internalClose()
    {
        super.close();
        isClosed = true;
    }
}

@@ -705,16 +705,68 @@
 Counter;
+%0Aimport org.agrona.concurrent.status.CountersReader;
 %0A%0A/**%0A *
@@ -1344,32 +1344,899 @@
 nductor;%0A    %7D%0A%0A
+    /**%0A     * Construct a read-write view of an existing counter.%0A     *%0A     * @param countersReader for getting access to the buffers.%0A     * @param registrationId assigned by the driver for the counter or -1 if not known.%0A     * @param counterId      for the counter to be viewed.%0A     * @throws IllegalStateException if the id has for the counter has not been allocated.%0A     */%0A    Counter(%0A        final CountersReader countersReader,%0A        final long registrationId,%0A        final int counterId)%0A    %7B%0A        super(countersReader.valuesBuffer(), counterId);%0A%0A        if (countersReader.getCounterState(counterId) != CountersReader.RECORD_ALLOCATED)%0A        %7B%0A            throw new IllegalStateException(%22Counter id has not been allocated: %22 + counterId);%0A        %7D%0A%0A        this.registrationId = registrationId;%0A        this.clientConductor = null;%0A    %7D%0A%0A
     /**%0A     * R
@@ -2473,27 +2473,19 @@
 nter
- which will
+,
  releas
-e
+ing
  the
@@ -2513,32 +2513,71 @@
 the media driver
+ if this was the creator of the Counter
 .%0A     * %3Cp%3E%0A   
@@ -2657,45 +2657,168 @@
     
-clientConductor.releaseCounter(this);
+if (null != clientConductor)%0A        %7B%0A            clientConductor.releaseCounter(this);%0A        %7D%0A        else%0A        %7B%0A            isClosed = true;%0A        %7D
 %0A   

add constructor for creating r/w views on Counters.