This is an automated email from the ASF dual-hosted git repository.

twolf pushed a commit to branch dev_3.0
in repository https://gitbox.apache.org/repos/asf/mina-sshd.git

commit d04cc45845c301bca9f60487c71f53479e19068d
Author: Thomas Wolf <tw...@apache.org>
AuthorDate: Thu Apr 24 21:00:32 2025 +0200

    An OpenSshCertificate is not a PrivateKey!
    
    Remove the interface. Handle this like the SK keys: specify the private
    key type in the decoder as PrivateKey.
    
    Remove the decoder-by-key-class methods and maps; they are not needed
    and, as the now removed comment pointed out, fragile.
---
 .../apache/sshd/common/config/keys/KeyUtils.java   | 128 ++++-----------------
 .../common/config/keys/OpenSshCertificate.java     |   3 +-
 .../keys/impl/OpenSSHCertificateDecoder.java       |  30 ++---
 .../openssh/OpenSSHKeyPairResourceParser.java      |  50 +-------
 4 files changed, 42 insertions(+), 169 deletions(-)

diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/config/keys/KeyUtils.java 
b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/KeyUtils.java
index b53a3ea78..357635eeb 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/config/keys/KeyUtils.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/KeyUtils.java
@@ -54,7 +54,6 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.EnumSet;
 import java.util.HashSet;
-import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.NavigableSet;
@@ -147,10 +146,6 @@ public final class KeyUtils {
     private static final Map<String, PublicKeyEntryDecoder<?, ?>> 
BY_KEY_TYPE_DECODERS_MAP
             = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
 
-    // order matters here, when, for example, SkED25519PublicKeyEntryDecoder 
is used, it registers the PrivateKey
-    // type as java.security.PrivateKey, and all PrivateKey types are 
assignable to this, so it must be consulted last
-    private static final Map<Class<?>, PublicKeyEntryDecoder<?, ?>> 
BY_KEY_CLASS_DECODERS_MAP = new LinkedHashMap<>();
-
     private static final Map<String, String> KEY_TYPE_ALIASES
             = NavigableMapBuilder.<String, String> 
builder(String.CASE_INSENSITIVE_ORDER)
                     .put(RSA_SHA256_KEY_TYPE_ALIAS, KeyPairProvider.SSH_RSA)
@@ -355,7 +350,7 @@ public final class KeyUtils {
      * @return                          A {@link KeyPair} of the specified 
type and size
      * @throws GeneralSecurityException If failed to generate the key pair
      * @see                             #getPublicKeyEntryDecoder(String)
-     * @see                             
PublicKeyEntryDecoder#generateKeyPair(int)
+     * @see                             PublicKeyEntryDecoder<?, 
?>#generateKeyPair(int)
      */
     public static KeyPair generateKeyPair(String keyType, int keySize) throws 
GeneralSecurityException {
         PublicKeyEntryDecoder<?, ?> decoder = 
getPublicKeyEntryDecoder(keyType);
@@ -385,88 +380,33 @@ public final class KeyUtils {
     }
 
     /**
-     * @param  decoder                  The decoder to register
-     * @throws IllegalArgumentException if no decoder or not key type or no 
supported names for the decoder
-     * @see                             
PublicKeyEntryDecoder#getPublicKeyType()
-     * @see                             
PublicKeyEntryDecoder#getSupportedKeyTypes()
-     */
-    public static void registerPublicKeyEntryDecoder(PublicKeyEntryDecoder<?, 
?> decoder) {
-        Objects.requireNonNull(decoder, "No decoder specified");
-
-        Class<?> pubType = Objects.requireNonNull(decoder.getPublicKeyType(), 
"No public key type declared");
-        Class<?> prvType = Objects.requireNonNull(decoder.getPrivateKeyType(), 
"No private key type declared");
-        synchronized (BY_KEY_CLASS_DECODERS_MAP) {
-            BY_KEY_CLASS_DECODERS_MAP.put(pubType, decoder);
-            BY_KEY_CLASS_DECODERS_MAP.put(prvType, decoder);
-        }
-
-        registerPublicKeyEntryDecoderKeyTypes(decoder);
-    }
-
-    /**
-     * Registers the specified decoder for all the types it {@link 
PublicKeyEntryDecoder#getSupportedKeyTypes()
+     * Registers the specified decoder for all the types it {@link 
PublicKeyEntryDecoder<?, ?>#getSupportedKeyTypes()
      * supports}
      *
-     * @param decoder The (never {@code null}) {@link PublicKeyEntryDecoder 
decoder} to register
-     * @see           #registerPublicKeyEntryDecoderForKeyType(String, 
PublicKeyEntryDecoder)
+     * @param decoder The (never {@code null}) {@link PublicKeyEntryDecoder<?, 
?> decoder} to register
+     * @see           #registerPublicKeyEntryDecoderForKeyType(String, 
PublicKeyEntryDecoder<?, ?>)
      */
-    public static void 
registerPublicKeyEntryDecoderKeyTypes(PublicKeyEntryDecoder<?, ?> decoder) {
+    public static void registerPublicKeyEntryDecoder(PublicKeyEntryDecoder<?, 
?> decoder) {
         Objects.requireNonNull(decoder, "No decoder specified");
 
         Collection<String> names
                 = 
ValidateUtils.checkNotNullAndNotEmpty(decoder.getSupportedKeyTypes(), "No 
supported key types");
-        for (String n : names) {
-            PublicKeyEntryDecoder<?, ?> prev = 
registerPublicKeyEntryDecoderForKeyType(n, decoder);
-            if (prev != null) {
-                // noinspection UnnecessaryContinue
-                continue; // debug breakpoint
-            }
-        }
-    }
-
-    /**
-     * @param  keyType The key (never {@code null}/empty) key type
-     * @param  decoder The (never {@code null}) {@link PublicKeyEntryDecoder 
decoder} to register
-     * @return         The previously registered decoder for this key type - 
{@code null} if none
-     */
-    public static PublicKeyEntryDecoder<?, ?> 
registerPublicKeyEntryDecoderForKeyType(
-            String keyType, PublicKeyEntryDecoder<?, ?> decoder) {
-        keyType = ValidateUtils.checkNotNullAndNotEmpty(keyType, "No key type 
specified");
-        Objects.requireNonNull(decoder, "No decoder specified");
-
         synchronized (BY_KEY_TYPE_DECODERS_MAP) {
-            return BY_KEY_TYPE_DECODERS_MAP.put(keyType, decoder);
-        }
-    }
-
-    /**
-     * @param  decoder The (never {@code null}) {@link PublicKeyEntryDecoder 
decoder} to unregister
-     * @return         The case <U>insensitive</U> {@link NavigableSet} of all 
the effectively un-registered key types
-     *                 out of all the {@link 
PublicKeyEntryDecoder#getSupportedKeyTypes() supported} ones.
-     * @see            
#unregisterPublicKeyEntryDecoderKeyTypes(PublicKeyEntryDecoder)
-     */
-    public static NavigableSet<String> 
unregisterPublicKeyEntryDecoder(PublicKeyEntryDecoder<?, ?> decoder) {
-        Objects.requireNonNull(decoder, "No decoder specified");
-
-        Class<?> pubType = Objects.requireNonNull(decoder.getPublicKeyType(), 
"No public key type declared");
-        Class<?> prvType = Objects.requireNonNull(decoder.getPrivateKeyType(), 
"No private key type declared");
-        synchronized (BY_KEY_CLASS_DECODERS_MAP) {
-            BY_KEY_CLASS_DECODERS_MAP.remove(pubType);
-            BY_KEY_CLASS_DECODERS_MAP.remove(prvType);
+            for (String keyType : names) {
+                BY_KEY_TYPE_DECODERS_MAP.put(keyType, decoder);
+            }
         }
-
-        return unregisterPublicKeyEntryDecoderKeyTypes(decoder);
     }
 
     /**
      * Unregisters the specified decoder for all the types it supports
      *
-     * @param  decoder The (never {@code null}) {@link PublicKeyEntryDecoder 
decoder} to unregister
+     * @param  decoder The (never {@code null}) {@link 
PublicKeyEntryDecoder<?, ?> decoder} to unregister
      * @return         The case <U>insensitive</U> {@link NavigableSet} of all 
the effectively un-registered key types
-     *                 out of all the {@link 
PublicKeyEntryDecoder#getSupportedKeyTypes() supported} ones.
+     *                 out of all the {@link PublicKeyEntryDecoder<?, 
?>#getSupportedKeyTypes() supported} ones.
      * @see            #unregisterPublicKeyEntryDecoderForKeyType(String)
      */
-    public static NavigableSet<String> 
unregisterPublicKeyEntryDecoderKeyTypes(PublicKeyEntryDecoder<?, ?> decoder) {
+    public static NavigableSet<String> 
unregisterPublicKeyEntryDecoder(PublicKeyEntryDecoder<?, ?> decoder) {
         Objects.requireNonNull(decoder, "No decoder specified");
 
         Collection<String> names = ValidateUtils.checkNotNullAndNotEmpty(
@@ -495,8 +435,8 @@ public final class KeyUtils {
      * Unregister the decoder registered for the specified key type
      *
      * @param  keyType The key (never {@code null}/empty) key type
-     * @return         The unregistered {@link PublicKeyEntryDecoder} - {@code 
null} if none registered for this key
-     *                 type
+     * @return         The unregistered {@link PublicKeyEntryDecoder<?, ?>} - 
{@code null} if none registered for this
+     *                 key type
      */
     public static PublicKeyEntryDecoder<?, ?> 
unregisterPublicKeyEntryDecoderForKeyType(String keyType) {
         keyType = ValidateUtils.checkNotNullAndNotEmpty(keyType, "No key type 
specified");
@@ -509,7 +449,7 @@ public final class KeyUtils {
     /**
      * @param  keyType The {@code OpenSSH} key type string - e.g., {@code 
ssh-rsa, ssh-dss} - ignored if
      *                 {@code null}/empty
-     * @return         The registered {@link PublicKeyEntryDecoder} or {code 
null} if not found
+     * @return         The registered {@link PublicKeyEntryDecoder<?, ?>} or 
{code null} if not found
      */
     public static PublicKeyEntryDecoder<?, ?> getPublicKeyEntryDecoder(String 
keyType) {
         if (GenericUtils.isEmpty(keyType)) {
@@ -523,8 +463,8 @@ public final class KeyUtils {
 
     /**
      * @param  kp The {@link KeyPair} to examine - ignored if {@code null}
-     * @return    The matching {@link PublicKeyEntryDecoder} provided 
<U>both</U> the public and private keys have the
-     *            same decoder - {@code null} if no match found
+     * @return    The matching {@link PublicKeyEntryDecoder<?, ?>} provided 
<U>both</U> the public and private keys have
+     *            the same decoder - {@code null} if no match found
      * @see       #getPublicKeyEntryDecoder(Key)
      */
     public static PublicKeyEntryDecoder<?, ?> getPublicKeyEntryDecoder(KeyPair 
kp) {
@@ -543,45 +483,17 @@ public final class KeyUtils {
 
     /**
      * @param  key The {@link Key} (public or private) - ignored if {@code 
null}
-     * @return     The registered {@link PublicKeyEntryDecoder} for this key 
or {code null} if no match found
+     * @return     The registered {@link PublicKeyEntryDecoder<?, ?>} for this 
key or {code null} if no match found
      * @see        #getPublicKeyEntryDecoder(Class)
      */
     public static PublicKeyEntryDecoder<?, ?> getPublicKeyEntryDecoder(Key 
key) {
         if (key == null) {
             return null;
         } else {
-            return getPublicKeyEntryDecoder(key.getClass());
+            return getPublicKeyEntryDecoder(KeyUtils.getKeyType(key));
         }
     }
 
-    /**
-     * @param  keyType The key {@link Class} - ignored if {@code null} or not 
a {@link Key} compatible type
-     * @return         The registered {@link PublicKeyEntryDecoder} or {code 
null} if no match found
-     */
-    public static PublicKeyEntryDecoder<?, ?> 
getPublicKeyEntryDecoder(Class<?> keyType) {
-        if ((keyType == null) || (!Key.class.isAssignableFrom(keyType))) {
-            return null;
-        }
-
-        synchronized (BY_KEY_TYPE_DECODERS_MAP) {
-            PublicKeyEntryDecoder<?, ?> decoder = 
BY_KEY_CLASS_DECODERS_MAP.get(keyType);
-            if (decoder != null) {
-                return decoder;
-            }
-
-            // in case it is a derived class
-            for (PublicKeyEntryDecoder<?, ?> dec : 
BY_KEY_CLASS_DECODERS_MAP.values()) {
-                Class<?> pubType = dec.getPublicKeyType();
-                Class<?> prvType = dec.getPrivateKeyType();
-                if (pubType.isAssignableFrom(keyType) || 
prvType.isAssignableFrom(keyType)) {
-                    return dec;
-                }
-            }
-        }
-
-        return null;
-    }
-
     /**
      * @return The default {@link DigestFactory} by the {@link 
#getFingerPrint(PublicKey)} and
      *         {@link #getFingerPrint(String)} methods
@@ -837,7 +749,7 @@ public final class KeyUtils {
     /**
      * @param  kp a key pair - ignored if {@code null}. If the private key is 
non-{@code null} then it is used to
      *            determine the type, otherwise the public one is used.
-     * @return    the key type or {@code null} if cannot determine it
+     * @return    the SSH key type or {@code null} if cannot determine it
      * @see       #getKeyType(Key)
      */
     public static String getKeyType(KeyPair kp) {
@@ -854,7 +766,7 @@ public final class KeyUtils {
 
     /**
      * @param  key a public or private key
-     * @return     the key type or {@code null} if cannot determine it
+     * @return     the SSH key type or {@code null} if cannot determine it
      */
     public static String getKeyType(Key key) {
         if (key == null) {
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/config/keys/OpenSshCertificate.java
 
b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/OpenSshCertificate.java
index f9f0cef30..ab3e230a1 100644
--- 
a/sshd-common/src/main/java/org/apache/sshd/common/config/keys/OpenSshCertificate.java
+++ 
b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/OpenSshCertificate.java
@@ -18,7 +18,6 @@
  */
 package org.apache.sshd.common.config.keys;
 
-import java.security.PrivateKey;
 import java.security.PublicKey;
 import java.time.Instant;
 import java.util.Arrays;
@@ -37,7 +36,7 @@ import org.apache.sshd.common.util.ValidateUtils;
  * @author <a href="mailto:d...@mina.apache.org";>Apache MINA SSHD Project</a>
  * @see    <a href= 
"https://cvsweb.openbsd.org/src/usr.bin/ssh/PROTOCOL.certkeys?annotate=HEAD";>PROTOCOL.certkeys</a>
  */
-public interface OpenSshCertificate extends SshPublicKey, PrivateKey {
+public interface OpenSshCertificate extends SshPublicKey {
 
     /**
      * {@link OpenSshCertificate}s have a type indicating whether the 
certificate if for a host key (certifying a host
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/config/keys/impl/OpenSSHCertificateDecoder.java
 
b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/impl/OpenSSHCertificateDecoder.java
index b6fa7a9f5..68822e7ce 100644
--- 
a/sshd-common/src/main/java/org/apache/sshd/common/config/keys/impl/OpenSSHCertificateDecoder.java
+++ 
b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/impl/OpenSSHCertificateDecoder.java
@@ -26,7 +26,9 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.security.GeneralSecurityException;
 import java.security.KeyFactory;
+import java.security.KeyPair;
 import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Map;
@@ -43,11 +45,11 @@ import org.apache.sshd.common.util.io.IoUtils;
 /**
  * @author <a href="mailto:d...@mina.apache.org";>Apache MINA SSHD Project</a>
  */
-public class OpenSSHCertificateDecoder extends 
AbstractPublicKeyEntryDecoder<OpenSshCertificate, OpenSshCertificate> {
+public class OpenSSHCertificateDecoder extends 
AbstractPublicKeyEntryDecoder<OpenSshCertificate, PrivateKey> {
     public static final OpenSSHCertificateDecoder INSTANCE = new 
OpenSSHCertificateDecoder();
 
     public OpenSSHCertificateDecoder() {
-        super(OpenSshCertificate.class, OpenSshCertificate.class,
+        super(OpenSshCertificate.class, PrivateKey.class,
               Collections.unmodifiableList(Arrays.asList(
                       KeyUtils.RSA_SHA256_CERT_TYPE_ALIAS,
                       KeyUtils.RSA_SHA512_CERT_TYPE_ALIAS,
@@ -72,9 +74,7 @@ public class OpenSSHCertificateDecoder extends 
AbstractPublicKeyEntryDecoder<Ope
         buffer.putString(keyType);
         buffer.putRawBytes(IoUtils.toByteArray(keyData));
         buffer.getString(); // Skip the key type just prepended
-        OpenSshCertificate cert = 
OpenSSHCertPublicKeyParser.INSTANCE.getRawPublicKey(keyType, buffer);
-
-        return cert;
+        return OpenSSHCertPublicKeyParser.INSTANCE.getRawPublicKey(keyType, 
buffer);
     }
 
     @Override
@@ -82,8 +82,7 @@ public class OpenSSHCertificateDecoder extends 
AbstractPublicKeyEntryDecoder<Ope
         Objects.requireNonNull(key, "No public key provided");
 
         ByteArrayBuffer buffer = new ByteArrayBuffer();
-        // use Buffer.putRawPublicKey so the certificate type is prepended
-        buffer.putRawPublicKey(key);
+        buffer.putRawPublicKey(key); // prepends the certificate type
         s.write(buffer.getCompactData());
 
         return key.getKeyType();
@@ -102,17 +101,22 @@ public class OpenSSHCertificateDecoder extends 
AbstractPublicKeyEntryDecoder<Ope
     }
 
     @Override
-    public OpenSshCertificate clonePrivateKey(OpenSshCertificate key) throws 
GeneralSecurityException {
-        return clonePublicKey(key);
+    public PrivateKey clonePrivateKey(PrivateKey key) {
+        throw new UnsupportedOperationException("Private key operations are 
not supported for certificates.");
+    }
+
+    @Override
+    public KeyFactory getKeyFactoryInstance() {
+        throw new UnsupportedOperationException("Private key operations are 
not supported for certificates.");
     }
 
     @Override
-    public KeyPairGenerator getKeyPairGenerator() throws 
GeneralSecurityException {
-        return null;
+    public KeyPair generateKeyPair(int keySize) {
+        throw new UnsupportedOperationException("Private key operations are 
not supported for certificates.");
     }
 
     @Override
-    public KeyFactory getKeyFactoryInstance() throws GeneralSecurityException {
-        return null;
+    public KeyPairGenerator getKeyPairGenerator() {
+        throw new UnsupportedOperationException("Private key operations are 
not supported for certificates.");
     }
 }
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/config/keys/loader/openssh/OpenSSHKeyPairResourceParser.java
 
b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/loader/openssh/OpenSSHKeyPairResourceParser.java
index 3fd1c1d5a..a28989375 100644
--- 
a/sshd-common/src/main/java/org/apache/sshd/common/config/keys/loader/openssh/OpenSSHKeyPairResourceParser.java
+++ 
b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/loader/openssh/OpenSSHKeyPairResourceParser.java
@@ -36,7 +36,6 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -83,8 +82,6 @@ public class OpenSSHKeyPairResourceParser extends 
AbstractKeyPairResourceParser
     private static final Map<String, PrivateKeyEntryDecoder<?, ?>> 
BY_KEY_TYPE_DECODERS_MAP
             = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
 
-    private static final Map<Class<?>, PrivateKeyEntryDecoder<?, ?>> 
BY_KEY_CLASS_DECODERS_MAP = new HashMap<>();
-
     static {
         registerPrivateKeyEntryDecoder(OpenSSHRSAPrivateKeyDecoder.INSTANCE);
         
registerPrivateKeyEntryDecoder(OpenSSHDSSPrivateKeyEntryDecoder.INSTANCE);
@@ -279,7 +276,7 @@ public class OpenSSHKeyPairResourceParser extends 
AbstractKeyPairResourceParser
 
             if (traceEnabled) {
                 log.trace("extractKeyPairs({}) add private key #{}: {} {}",
-                        resourceKey, keyIndex, prvType, prvData.getValue());
+                        resourceKey, keyIndex, prvType, prvData == null ? "" : 
prvData.getValue());
             }
             keyPairs.add(new KeyPair(pubKey, prvKey));
         }
@@ -345,22 +342,11 @@ public class OpenSSHKeyPairResourceParser extends 
AbstractKeyPairResourceParser
     public static void 
registerPrivateKeyEntryDecoder(PrivateKeyEntryDecoder<?, ?> decoder) {
         Objects.requireNonNull(decoder, "No decoder specified");
 
-        Class<?> pubType = Objects.requireNonNull(decoder.getPublicKeyType(), 
"No public key type declared");
-        Class<?> prvType = Objects.requireNonNull(decoder.getPrivateKeyType(), 
"No private key type declared");
-        synchronized (BY_KEY_CLASS_DECODERS_MAP) {
-            BY_KEY_CLASS_DECODERS_MAP.put(pubType, decoder);
-            BY_KEY_CLASS_DECODERS_MAP.put(prvType, decoder);
-        }
-
         Collection<String> names
                 = 
ValidateUtils.checkNotNullAndNotEmpty(decoder.getSupportedKeyTypes(), "No 
supported key type");
         synchronized (BY_KEY_TYPE_DECODERS_MAP) {
-            for (String n : names) {
-                PrivateKeyEntryDecoder<?, ?> prev = 
BY_KEY_TYPE_DECODERS_MAP.put(n, decoder);
-                if (prev != null) {
-                    // noinspection UnnecessaryContinue
-                    continue; // debug breakpoint
-                }
+            for (String keyType : names) {
+                BY_KEY_TYPE_DECODERS_MAP.put(keyType, decoder);
             }
         }
     }
@@ -409,35 +395,7 @@ public class OpenSSHKeyPairResourceParser extends 
AbstractKeyPairResourceParser
         if (key == null) {
             return null;
         } else {
-            return getPrivateKeyEntryDecoder(key.getClass());
-        }
-    }
-
-    /**
-     * @param  keyType The key {@link Class} - ignored if {@code null} or not 
a {@link Key} compatible type
-     * @return         The registered {@link PrivateKeyEntryDecoder} or {code 
null} if no match found
-     */
-    public static PrivateKeyEntryDecoder<?, ?> 
getPrivateKeyEntryDecoder(Class<?> keyType) {
-        if ((keyType == null) || (!Key.class.isAssignableFrom(keyType))) {
-            return null;
-        }
-
-        synchronized (BY_KEY_TYPE_DECODERS_MAP) {
-            PrivateKeyEntryDecoder<?, ?> decoder = 
BY_KEY_CLASS_DECODERS_MAP.get(keyType);
-            if (decoder != null) {
-                return decoder;
-            }
-
-            // in case it is a derived class
-            for (PrivateKeyEntryDecoder<?, ?> dec : 
BY_KEY_CLASS_DECODERS_MAP.values()) {
-                Class<?> pubType = dec.getPublicKeyType();
-                Class<?> prvType = dec.getPrivateKeyType();
-                if (pubType.isAssignableFrom(keyType) || 
prvType.isAssignableFrom(keyType)) {
-                    return dec;
-                }
-            }
+            return getPrivateKeyEntryDecoder(KeyUtils.getKeyType(key));
         }
-
-        return null;
     }
 }

Reply via email to