package com.orbekk.util;

public class DelayedOperation {
    public static class Status {
        public final static int OK = 1;
        public final static int CONFLICT = 2;
        public final static int ERROR = 3;

        private int status;
        private String message;

        public static Status createOk() {
            return new Status(OK, "");
        }

        public static Status createConflict(String message) {
            return new Status(CONFLICT, message);
        }

        public static Status createError(String message) {
            return new Status(ERROR, message);
        }

        public Status(int status, String message) {
            this.status = status;
            this.message = message;
        }

        public boolean isOk() {
            return status == OK;
        }
        
        public int getStatusCode() {
            return status;
        }
        
        public String getMessage() {
            return message;
        }
        
        @Override public String toString() {
            switch(status) {
            case OK:
                return "OK";
            case CONFLICT:
                return "Conflicting update: " + message;
            case ERROR:
                return "Error: " + message;
            }
            throw new AssertionError("Unhandled case.");
        }

        @Override public boolean equals(Object other) {
            if (!(other instanceof Status)) {
                return false;
            }
            Status o = (Status)other;
            if (o.status != this.status) {
                return false;
            }
            if (message == null) {
                return o.message == null;
            }
            return message.equals(o.message);
        }
    }

    private Status status;
    private boolean isDone;
    private int identifier;

    public DelayedOperation() {
    }

    public Status getStatus() {
        waitFor();
        return status;
    }

    public synchronized void waitFor() {
        while (!isDone) {
            try {
                wait();
            } catch (InterruptedException e) {
                complete(new Status(Status.ERROR, "Thread interrupted."));
            }
        }
    }

    public synchronized boolean isDone() {
        return isDone;
    }

    public synchronized void complete(Status status) {
        if (!isDone) {
            isDone = true;
            this.status = status;
            notifyAll();
        }
    }

    public synchronized int getIdentifier() {
        return identifier;
    }

    public synchronized void setIdentifier(int identifier) {
        this.identifier = identifier;
    }
}

@@ -19,16 +19,61 @@
 .util;%0A%0A
+import java.util.concurrent.CountDownLatch;%0A%0A
 public c
@@ -1831,16 +1831,25 @@
 private 
+volatile 
 Status s
@@ -1867,30 +1867,39 @@
 private 
-boolean isDone
+volatile int identifier
 ;%0A    pr
@@ -1904,32 +1904,71 @@
 private 
+f
 in
-t identifier;%0A
+al CountDownLatch done = new CountDownLatch(1);%0A    
 %0A    pub
@@ -2087,37 +2087,24 @@
 %0A    public 
-synchronized 
 void waitFor
@@ -2112,38 +2112,8 @@
 ) %7B%0A
-        while (!isDone) %7B%0A    
     
@@ -2130,28 +2130,30 @@
             
-    
+done.a
 wait();%0A    
@@ -2156,20 +2156,16 @@
         
-    
 %7D catch 
@@ -2187,28 +2187,24 @@
 eption e) %7B%0A
-    
             
@@ -2266,33 +2266,67 @@
 ));%0A            
-%7D
+Thread.currentThread().interrupt();
 %0A        %7D%0A    %7D
@@ -2385,22 +2385,36 @@
  return 
-isDone
+done.getCount() %3C= 0
 ;%0A    %7D%0A
@@ -2473,62 +2473,8 @@
 ) %7B%0A
-        if (!isDone) %7B%0A            isDone = true;%0A    
     
@@ -2511,34 +2511,25 @@
     
-    notifyAll();%0A        %7D
+done.countDown();
 %0A   

Fix DelayedOperation.