private void Work() 
    {
        try
        {
            LOG.log(Level.INFO, "Entering work loop.");
            ArrayList<Transaction> incomingTransactions = null;
            Block CurrentBlock = null;
            long currentProof = 0;
            Random sr = new Random();
            ByteArrayOutputStream theBytes = new ByteArrayOutputStream();
            ObjectOutputStream oos =  new ObjectOutputStream(theBytes);
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            byte[] blockHash = null;
            byte[] saltHash = null;
            byte[] proofHash = null;
            HashMap<byte[], ArrayList<Transaction>> unspentTransCache = null;
            
            //Not synchronized access to this variable, however it's fine since at most we'll spend one more cycle working. 
            while(!this.interruptWork)
            {
                //Is this the first round for this block?
                if(CurrentBlock == null)
                {
                    CurrentBlock = new Block();
                    unspentTransCache = new HashMap<byte[], ArrayList<Transaction>>();
                    Transaction prize = createPrizeTransaction(this.currentAccount.getPublicKey());
                    CurrentBlock.setPrizeTransaction(prize);
                    if(bchain.getHash() != null)
                    {
                        CurrentBlock.setPreviousBlock(bchain.getHash());
                        CurrentBlock.setBlockChainPosition(bchain.getLenght() + 1);
                    }
                    else
                    CurrentBlock.setPreviousBlock(null);
                }
                
                //Check if new transactions in the work pool.
                incomingTransactions = this.pool.getAllTransactions();
                        
                if(incomingTransactions != null)
                {
                    CurrentBlock.addTransactions(incomingTransactions, this.tm, unspentTransCache);
                    
                    //If new transaction was added, reset the proof iterator to a new random.
                    currentProof = sr.nextLong();
                }
                        
                //Done with new transactions, now try to calculate the proof for this block.
                if(CurrentBlock.getTransactions().size() < 1 )
                {
                    //No work to be done. Sleep for some time and continue to the next iteration
                    Thread.sleep(100);
                    continue;
                }
                
                //Create SHA256 hash of proof and get bytes.
                oos.writeLong(currentProof);
                oos.flush();
                md.update(theBytes.toByteArray());
                saltHash = md.digest();
                
                //Get block bytes hash
                CurrentBlock.setProof(currentProof);
                blockHash = CurrentBlock.getHash();
  
                
                //Create SHA256 hash of the whole data set
                oos.write(blockHash);
                oos.write(saltHash);
                oos.flush();
                md.update(theBytes.toByteArray());
                proofHash = md.digest();
                
                ByteArrayInputStream bais = new ByteArrayInputStream(proofHash);
                DataInputStream dis = new DataInputStream(bais);
                
                if(dis.readLong() < getProofTest())
                {
                    //We have a winner!
                    //Commit Block
                    bchain.appendBlock(CurrentBlock);
                    
                    //Now remove them from the transaction pool
                    this.pool.removeIfExist(CurrentBlock.getRegularTrans());
                    
                    //Broadcast solution
                    (new StatMessage(CurrentBlock.getHash(), CurrentBlock.getBlockChainPosition())).bcast();
                    
                    CurrentBlock = null;
                    incomingTransactions = null;
                }
                else
                {
                    //Failed proof :( Increment the proof and try again.
                    currentProof++;
                }
            }
            
            //We have been signaled to stop working.
            LOG.log(Level.INFO, "Exiting work loop.");
        }
        catch (IOException e) 
        {
            LOG.log(Level.INFO, e.toString());
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) 
        {
            LOG.log(Level.INFO, e.toString());
            e.printStackTrace(); 
        }
        catch (InterruptedException e) 
        {
            LOG.log(Level.INFO, e.toString());
            e.printStackTrace();
    }
    }