/**
 * Copyright (c) 2014-2017 by the respective copyright holders.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 */
package org.eclipse.smarthome.core.thing.binding.builder;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.smarthome.config.core.Configuration;
import org.eclipse.smarthome.core.thing.Channel;
import org.eclipse.smarthome.core.thing.ChannelUID;
import org.eclipse.smarthome.core.thing.type.ChannelKind;
import org.eclipse.smarthome.core.thing.type.ChannelType;
import org.eclipse.smarthome.core.thing.type.ChannelTypeUID;

/**
 * {@link ChannelBuilder} is responsible for creating {@link Channel}s.
 *
 * @author Dennis Nobel - Initial contribution
 * @author Alex Tugarev - Extended about default tags
 * @author Chris Jackson - Added properties and label/description
 */
public class ChannelBuilder {

    private ChannelUID channelUID;
    private String acceptedItemType;
    private ChannelKind kind;
    private Configuration configuration;
    private Set<String> defaultTags;
    private Map<@NonNull String, String> properties;
    private String label;
    private String description;
    private ChannelTypeUID channelTypeUID;

    private ChannelBuilder(ChannelUID channelUID, String acceptedItemType, Set<String> defaultTags) {
        this.channelUID = channelUID;
        this.acceptedItemType = acceptedItemType;
        this.defaultTags = defaultTags;
        this.kind = ChannelKind.STATE;
    }

    /**
     * Creates a channel builder for the given channel UID and item type.
     *
     * @param channelUID
     *            channel UID
     * @param acceptedItemType
     *            item type that is accepted by this channel
     * @return channel builder
     */
    public @NonNull static ChannelBuilder create(@NonNull ChannelUID channelUID, @NonNull String acceptedItemType) {
        return new ChannelBuilder(channelUID, acceptedItemType, new HashSet<String>());
    }

    /**
     * Appends the channel type to the channel to build
     *
     * @param channelTypeUID channel type UID
     * @return channel builder
     */
    public @NonNull ChannelBuilder withType(@NonNull ChannelTypeUID channelTypeUID) {
        this.channelTypeUID = channelTypeUID;
        return this;
    }

    /**
     * Appends a configuration to the channel to build.
     *
     * @param configuration
     *            configuration
     * @return channel builder
     */
    public @NonNull ChannelBuilder withConfiguration(Configuration configuration) {
        this.configuration = configuration;
        return this;
    }

    /**
     * Adds properties to the channel
     *
     * @param properties properties to add
     * @return channel builder
     */
    public @NonNull ChannelBuilder withProperties(Map<@NonNull String, String> properties) {
        this.properties = properties;
        return this;
    }

    /**
     * Sets the channel label. This allows overriding of the default label set in the {@link ChannelType}
     *
     * @param label the channel label to override the label set in the {@link ChannelType}
     * @return channel builder
     */
    public @NonNull ChannelBuilder withLabel(String label) {
        this.label = label;
        return this;
    }

    /**
     * Sets the channel label. This allows overriding of the default label set in the {@link ChannelType}
     *
     * @param label the channel label to override the label set in the {@link ChannelType}
     * @return channel builder
     */
    public @NonNull ChannelBuilder withDescription(String description) {
        this.description = description;
        return this;
    }

    /**
     * Appends default tags to the channel to build.
     *
     * @param defaultTags
     *            default tags
     * @return channel builder
     */
    public @NonNull ChannelBuilder withDefaultTags(Set<String> defaultTags) {
        this.defaultTags = defaultTags;
        return this;
    }

    /**
     * Sets the kind of the channel.
     *
     * @param kind kind.
     * @return channel builder
     */
    public @NonNull ChannelBuilder withKind(ChannelKind kind) {
        if (kind == null) {
            throw new IllegalArgumentException("kind must not be null");
        }

        this.kind = kind;
        return this;
    }

    /**
     * Builds and returns the channel.
     *
     * @return channel
     */
    public @NonNull Channel build() {
        return new Channel(channelUID, channelTypeUID, acceptedItemType, kind, configuration, defaultTags, properties,
                label, description);
    }
}

@@ -482,16 +482,69 @@
 .NonNull
+ByDefault;%0Aimport org.eclipse.jdt.annotation.Nullable
 ;%0Aimport
@@ -1122,16 +1122,34 @@
 ion%0A */%0A
+@NonNullByDefault%0A
 public c
@@ -1214,24 +1214,34 @@
     private 
+@Nullable 
 String accep
@@ -1295,16 +1295,26 @@
 private 
+@Nullable 
 Configur
@@ -1383,29 +1383,30 @@
 private 
-Map%3C@NonNull 
+@Nullable Map%3C
 String, 
@@ -1433,24 +1433,34 @@
     private 
+@Nullable 
 String label
@@ -1473,16 +1473,26 @@
 private 
+@Nullable 
 String d
@@ -1511,24 +1511,34 @@
     private 
+@Nullable 
 ChannelTypeU
@@ -1606,16 +1606,26 @@
 nnelUID,
+ @Nullable
  String 
@@ -2129,25 +2129,16 @@
  public 
-@NonNull 
 static C
@@ -2158,25 +2158,16 @@
  create(
-@NonNull 
 ChannelU
@@ -2183,22 +2183,23 @@
 lUID, @N
-onN
 ull
+able
  String 
@@ -2476,33 +2476,24 @@
 %0A    public 
-@NonNull 
 ChannelBuild
@@ -2506,22 +2506,23 @@
 hType(@N
-onN
 ull
+able
  Channel
@@ -2798,33 +2798,24 @@
 %0A    public 
-@NonNull 
 ChannelBuild
@@ -3080,33 +3080,24 @@
 %0A    public 
-@NonNull 
 ChannelBuild
@@ -3118,25 +3118,16 @@
 ies(Map%3C
-@NonNull 
 String, 
@@ -3472,33 +3472,24 @@
 %0A    public 
-@NonNull 
 ChannelBuild
@@ -3831,33 +3831,24 @@
 %0A    public 
-@NonNull 
 ChannelBuild
@@ -4127,33 +4127,24 @@
 %0A    public 
-@NonNull 
 ChannelBuild
@@ -4380,33 +4380,24 @@
 %0A    public 
-@NonNull 
 ChannelBuild
@@ -4694,17 +4694,8 @@
 lic 
-@NonNull 
 Chan

Fix Nullannotation problem (#4297)