/// <summary>
        ///     - allTopics=true - request all topics from cluster
        ///     - allTopics=false, topic=null - request only locally known topics (topic_new():ed topics or otherwise locally referenced once, such as consumed topics)
        ///     - allTopics=false, topic=valid - request specific topic
        /// </summary>
        internal Metadata GetMetadata(bool allTopics, SafeTopicHandle topic, int millisecondsTimeout)
        {
            ThrowIfHandleClosed();
            IntPtr    metaPtr;
            ErrorCode err = LibRdKafka.metadata(
                handle, allTopics,
                topic?.DangerousGetHandle() ?? IntPtr.Zero,
                /* const struct rd_kafka_metadata ** */ out metaPtr,
                (IntPtr)millisecondsTimeout);

            if (err == ErrorCode.NoError)
            {
                try {
                    var meta = Util.Marshal.PtrToStructure <rd_kafka_metadata>(metaPtr);

                    var brokers = Enumerable.Range(0, meta.broker_cnt)
                                  .Select(i => Util.Marshal.PtrToStructure <rd_kafka_metadata_broker>(
                                              meta.brokers + i * Util.Marshal.SizeOf <rd_kafka_metadata_broker>()))
                                  .Select(b => new BrokerMetadata(b.id, b.host, b.port))
                                  .ToList();

                    var topics = Enumerable.Range(0, meta.topic_cnt)
                                 .Select(i => Util.Marshal.PtrToStructure <rd_kafka_metadata_topic>(
                                             meta.topics + i * Util.Marshal.SizeOf <rd_kafka_metadata_topic>()))
                                 .Select(t => new TopicMetadata(
                                             t.topic,
                                             Enumerable.Range(0, t.partition_cnt)
                                             .Select(j => Util.Marshal.PtrToStructure <rd_kafka_metadata_partition>(
                                                         t.partitions + j * Util.Marshal.SizeOf <rd_kafka_metadata_partition>()))
                                             .Select(p => new PartitionMetadata(
                                                         p.id,
                                                         p.leader,
                                                         MarshalCopy(p.replicas, p.replica_cnt),
                                                         MarshalCopy(p.isrs, p.isr_cnt),
                                                         p.err
                                                         ))
                                             .ToList(),
                                             t.err
                                             ))
                                 .ToList();

                    return(new Metadata(
                               brokers,
                               topics,
                               meta.orig_broker_id,
                               meta.orig_broker_name
                               ));
                }
                finally
                {
                    LibRdKafka.metadata_destroy(metaPtr);
                }
            }
            else
            {
                throw new KafkaException(err);
            }
        }
        internal void Seek(string topic, int partition, long offset, int millisecondsTimeout)
        {
            ThrowIfHandleClosed();
            SafeTopicHandle rtk    = Topic(topic, IntPtr.Zero);
            var             result = LibRdKafka.seek(rtk.DangerousGetHandle(), partition, offset, (IntPtr)millisecondsTimeout);

            if (result != ErrorCode.NoError)
            {
                throw new KafkaException(result);
            }
        }