class CodeBlocks {

    @Nonnull
    public static CodeBlock createUnmodifiableStatement(@Nonnull TypeMirror type, @Nonnull String variable) {
        if (type.getKind() == TypeKind.ARRAY) {
            return CodeBlock.of("$T.copyOf($N, $N.length)", Arrays.class, variable, variable);
        }

        if (MoreTypes.isTypeOf(List.class, type)) {
            return CodeBlock.of("new $T<>($N)", ArrayList.class, variable);
        }

        if (MoreTypes.isTypeOf(Set.class, type)) {
            return CodeBlock.of("new $T<>($N)", HashSet.class, variable);
        }

        if (MoreTypes.isTypeOf(Map.class, type)) {
            return CodeBlock.of("new $T<>($N)", HashMap.class, variable);
        }
        return CodeBlock.of("$N", variable);
    }

}

class CodeBlocksTest {

    @Rule
    public CompilationRule compilationRule;
    private Elements elements;

    @Test
    public void createUnmodifiableStatementShouldCopyListDefensively() throws Exception {

        // setup
        final TypeElement element = elements.getTypeElement(List.class.getCanonicalName());
        final TypeMirror mirror = element.asType();

        // exercise
        final CodeBlock actual = CodeBlocks.createUnmodifiableStatement(mirror, "value");

        // verify
        assertThat(actual.toString())
                .isEqualTo("new java.util.ArrayList<>(value)");
    }

}