/*
 * Copyright (c) 2011 Stiftung Deutsches Elektronen-Synchrotron,
 * Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY.
 *
 * THIS SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "../AS IS" BASIS.
 * WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR PARTICULAR PURPOSE AND
 * NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
 * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. SHOULD THE SOFTWARE PROVE DEFECTIVE
 * IN ANY RESPECT, THE USER ASSUMES THE COST OF ANY NECESSARY SERVICING, REPAIR OR
 * CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE.
 * NO USE OF ANY SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
 * DESY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
 * OR MODIFICATIONS.
 * THE FULL LICENSE SPECIFYING FOR THE SOFTWARE THE REDISTRIBUTION, MODIFICATION,
 * USAGE AND OTHER RIGHTS AND OBLIGATIONS IS INCLUDED WITH THE DISTRIBUTION OF THIS
 * PROJECT IN THE FILE LICENSE.HTML. IF THE LICENSE IS NOT INCLUDED YOU MAY FIND A COPY
 * AT HTTP://WWW.DESY.DE/LEGAL/LICENSE.HTM
 */
package org.csstudio.domain.desy.typesupport;

import javax.annotation.Nonnull;

import org.epics.pvmanager.TypeSupport;

/**
 * Abstract type support to encapsulate some methods from {@link TypeSupport} that
 * do not act as we'd like them to.
 *
 * @author bknerr
 * @since Mar 30, 2011
 * @param <T> the type parameter for this support's discriminator
 */
public abstract class AbstractTypeSupport<T> extends TypeSupport<T> {

    /**
     * Constructor.
     */
    protected AbstractTypeSupport(@Nonnull final Class<T> type,
                               @SuppressWarnings("rawtypes") @Nonnull final Class<? extends TypeSupport> typeSupportFamily) {
        super(type, typeSupportFamily);
    }

    @Nonnull
    protected static <T> TypeSupport<T> findTypeSupportForOrThrowTSE(@SuppressWarnings("rawtypes") @Nonnull final Class<? extends TypeSupport> supportFamily,
                                                                     @Nonnull final Class<T> typeClass)
                                                                     throws TypeSupportException {
        try {
            final TypeSupport<T> support = findTypeSupportFor(supportFamily, typeClass);
            if (support != null) {
                return support;
            }
        // CHECKSTYLE OFF: EmptyBlock
        } catch (final RuntimeException e) {
            // Ignore
        }
        // CHECKSTYLE ON: EmptyBlock
        throw new TypeSupportException("Type support for " + typeClass.getName() + " not present in family " + supportFamily.getName(), null);
    }

    public static <T> void installIfNotExists(@SuppressWarnings("rawtypes") @Nonnull final Class<? extends TypeSupport> family,
                                              @Nonnull final Class<T> type,
                                              @Nonnull final AbstractTypeSupport<T> support) {
        try {
            findTypeSupportForOrThrowTSE(family, type);
        } catch (final TypeSupportException e) {
            addTypeSupport(support);
        }
    }
}

@@ -1976,28 +1976,17 @@
 upport%3E 
-typeSupportF
+f
 amily) %7B
@@ -2010,20 +2010,9 @@
 pe, 
-typeSupportF
+f
 amil
@@ -2178,24 +2178,17 @@
 upport%3E 
-supportF
+f
 amily,%0A 
@@ -2283,21 +2283,16 @@
 %3CT%3E type
-Class
 )%0A      
@@ -2396,336 +2396,50 @@
     
-try %7B%0A            final TypeSupport%3CT%3E support = findTypeSupportFor(supportFamily, typeClass);%0A            if (support != null) %7B%0A                return support;%0A            %7D%0A        // CHECKSTYLE OFF: EmptyBlock%0A        %7D catch (final RuntimeException e) %7B%0A            // Ignore%0A        %7D%0A        // CHECKSTYLE ON: EmptyBlock%0A
+if (!isTypeSupported(family, type)) %7B%0A    
     
@@ -2499,21 +2499,16 @@
 %22 + type
-Class
 .getName
@@ -2544,16 +2544,9 @@
 %22 + 
-supportF
+f
 amil
@@ -2565,16 +2565,75 @@
  null);%0A
+        %7D%0A        return findTypeSupportFor(family, type);%0A
     %7D%0A%0A 
@@ -2942,115 +2942,50 @@
     
-try %7B%0A            findTypeSupportForOrThrowTSE(family, type);%0A        %7D catch (final TypeSupportException e
+if (!isTypeDirectlySupported(family, type)
 ) %7B%0A

use new TypeSupport API that checks for existing supports