Minecraft Chest Placement The video game Minecraft is all about placing and removing different types of blocks in the 3D integer lattice that makes up the virtual world. Each lattice point can contain exactly one block or be empty (an "air" block officially). In this challenge, we will only be concerned with one horizontal 2D plane of the 3D world, and one type of block: chests.

Chests let players store items. When two chests are orthogonally adjacent in the same horizontal plane, their textures link up and a double chest with twice the capacity forms. Nothing bigger than a double chest can be made; there are no triple chests nor quadruple chests.

A chest block can only be placed in an empty lattice point if its four orthogonally adjacent points are all empty, or if exactly one contains a chest block that is not already part of a double chest. These placement rules ensure that there can never be any ambiguity about which chest blocks link to form double chests.

For example, suppose . is empty space and C is a chest: (The numbers are also empty space and just for identification purposes.)

.......C..
.1.C2.C3..
........5C
.CC4..CC..
..........



A chest can be placed in spot 1 because its 4 neighbors are empty.
A chest can be placed in spot 2 because the neighboring chest is not (yet) part of a double chest.
A chest can't be put in spot 3 because there would be ambiguity over how the double chest forms.
A chest can't be placed in spot 4 because the neighboring chest is already part of a double chest.
A chest can be placed in spot 5. The diagonally neighboring double chest doesn't affect anything.


Assuming the area beyond the grid is empty, changing every . in the grid to a * if a chest could be placed there results in this:

******.C**
***C**C.**
*..***..*C
.CC.*.CC.*
*..***..**


Not all of the * spaces can be occupied with chests at the same time of course, but if you only had one chest, it could be placed in any of them.

Challenge

Write a program or function that takes in a . and C grid, and changes every . to a * if a chest could be placed there, printing or returning the resulting grid.


Input can be from stdin or a file or as a string argument to a function. 
You may assume the input is well formed - i.e. a perfectly rectangular grid of text, at least 1 character wide and tall, only containing . and C You may optionally assume there is a trailing newline after the last row (and there may be one in the output).
You may assume the arrangement of chests in the input is consistent with the rules above. There will never be ambiguities about which chests form double chests.
If desired, you may use any three distinct printable ASCII characters in place of ., C, and *. You may not use something else in place of newlines.
All the chests are normal chests. Not trapped chests or ender chests.


Scoring

The submission with the fewest bytes wins.

For a Minecraft related challenge that's a bit more challenging, try Nether Portal Detection.
CJam, 82 76 66 62 58 54 bytes

qN/::~4{[8_]f/[9_]f*z{[{1$8-g)+}*]W%}%}*{_8&lt;\2&lt;8?}f%N*


Input format expects 0 for air cell and 8 for a chest cell. Output contains 1 for all cells that can be placed with a Chest.

UPDATE : Fixed a bug. Increased by 3 bytes :( golfed further :) . 4 bytes saved thanks to @Sp3000

Example input:

0000000800
0008008000
0000000008
0880008808
0000000000


Output:

1111110811
1110018010
1008800108
0880088008
1008800110


I think I am done golfing for now...

Explanation

qN/::~                   "This part converts the input into array of integer array";
qN/                      "Split input on new line";
   ::~                   "Parse each character in each row as integer";

4{[8_]f/[9_]f*z{[{1$8-g)+}*]W%}%}*

4{   ...z{       W%}%}*  "Run the logic 4 times, first, columns in correct order, then,";
                         "columns in reverse order, then for rows";
  [8_]f/[9_]f*           "Convert adjacent chests represented by two 8 into two 9";
                         "This happens for all the rows in the columns iterations and";
                         "for all the columns in the rows iterations";
  {               }%     "For each row/column";
   [{        }*]         "Reduce and wrap it back in the array";
     :I8-                "Store the second number in I, remove 8 from it";
         g               "Do signum. Now we have -1 for &lt; 8 number, 0 for 8 and 1 for &gt; 8";
          )+I            "Increment to get 0, 1 &amp; 2. Add it to first number and put I back";

{_8&lt;\2&lt;8?}f%N*           "This part converts the output from previous iterations";
                         "to 3 character based final output and prints it";
{        }f%             "Map each row using the code block";
 _8&lt;   8?                "If the value is greater than 7, make it 8, else:";
    \2&lt;                  "If the value is greater than 1, make it 0, else 1";
            N*           "Join the arrays using new line";


Try it online here